Monday 30 January 2012

JPA: @OneToMany error: Field 'usersB_ID' doesn't have a default value

Moral: If you use @OneToMany always declare @JoinTable

Code with error:

@Entity
public class Users {

  @OneToMany
  public Set getUsersA() { return usersA; }


  @OneToMany
  public Set getUsersB() { return usersB; }

}


Problem description: In a @OneToMany relationship is you don't specify a join table then JPA creates one with the combined name of the outer class and the return type of the getter, i.e. in our case Users_User. Since usersA and usersB are of the same class then JPA creates only one join table. When we add a User in (e.g.) usersA and persist/merge Users in db then an sql cmd such as the following is executed:
insert into Users_user (Users_ID, users_ID) values (1,3)
but Users_user has 3 columns: id, FK to User class because of getUsersA(), FK to User class because of getUsersB(). But the 3rd column remains null in the previous sql statement and therefore an error is thrown: Field 'usersB_ID' doesn't have a default value

Solution: Create 2 join tables

@Entity
public class Users {

  @OneToMany
  @JoinTable
   (
       name="Users_usersA",
       joinColumns={ @JoinColumn(name="Users_ID", referencedColumnName="ID") },
       inverseJoinColumns={ @JoinColumn(name="USER_ID", referencedColumnName="ID") }
   )
  public Set getUsersA() { return usersA; }


  @OneToMany
  @JoinTable
   (
       name="Users_usersB",
       joinColumns={ @JoinColumn(name="Users_ID", referencedColumnName="ID") },
       inverseJoinColumns={ @JoinColumn(name="USER_ID", referencedColumnName="ID") }
   )
  public Set getUsersB() { return usersB; }

}


No comments:

Post a Comment