Search code examples
hibernatejpaormmany-to-many

Hibernate many-to-many join table not populating


I want to associate two entity classes User and Unit via a many-to-many association using a join table. However this is not working as intended. First I'll briefly show you what I got so far.

Database:

|    User    |   |  UserToUnit   |   |   Unit    |
|Id|login|...|   |User_Id|Unit_Id|   |Id|name|...|

Entity User:

    @Entity
    @Table(name = "\"User\"")
    public class User implements Identifiable {
        public User() {
            units = new ArrayList<Unit>();
        }

        @Id
        @GeneratedValue(generator = "increment")
        @GenericGenerator(name = "increment", strategy = "guid")
        @Column(name = "Id", columnDefinition = "uniqueidentifier")
        private String id;

        @Transient
        @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
        @JoinTable(name = "UserToUnit",
            joinColumns = { @JoinColumn(name = "User_Id", nullable = false, updatable = false) },
            inverseJoinColumns =  { @JoinColumn(name = "Unit_Id", nullable = false, updatable = false) }
        )
        private Collection<Unit> units;
        [...]
        public Collection<Unit> getUnits() {
            return units;
        }

        public void setUnits(Collection<Unit> ous) {
            units= ous;
        }
    }

Entity Unit:

@Entity
@Table(name = "Unit")
@XmlRootElement
public class Unit implements Identifiable {

public Unit() {
    users = new ArrayList<User>();
}

@Id
@GeneratedValue(generator = "increment")
@GenericGenerator(name = "increment", strategy = "guid")
@Column(name = "Id", columnDefinition = "uniqueidentifier")
private String id;

@Transient
@ManyToMany(fetch = FetchType.LAZY, mappedBy = "units")
private Collection<User> users;
[...]
public Collection<User> getUsers() {
    return users;
}

public void setUsers(Collection<User> us) {
    users = us;
}

Usage:

user.getUnits().add(unit);
unit.getUsers().add(user);
unitDAO.saveOrUpdate(unit);
userDAO.saveOrUpdate(user);

But this does not add anything to the UserToUnit table. What am I missing here? Cheers, Chris


Solution

  • What is the reason why you are using the @Transient annotation? You should be using that if you want to use property access and the getter is not following the field name.

    You are mixing field and property access, so you should also add @Access(AccessType.PROPERTY) to the getter method or move annotations to the field.