Jpa simple many-to-many with eclipselink

I have this ER chart:

enter image description here

This has been translated into these classes:

User.java

@Entity @Table(name = "user") @NamedQueries({ @NamedQuery(name = "User.findAll", query = "SELECT u FROM User u")}) public class User implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Basic(optional = false) @Column(name = "id") private Integer id; @Column(name = "name") private String name; @OneToMany(cascade = CascadeType.ALL, mappedBy = "user") private Collection<UserHasNotify> userHasNotifyCollection; 

UserHasNotify.java

 @Entity @Table(name = "user_has_notify") @NamedQueries({ @NamedQuery(name = "UserHasNotify.findAll", query = "SELECT u FROM UserHasNotify u")}) public class UserHasNotify implements Serializable { private static final long serialVersionUID = 1L; @EmbeddedId protected UserHasNotifyPK userHasNotifyPK; @Column(name = "has_read") private String hasRead; @JoinColumn(name = "notify_id", referencedColumnName = "id", insertable = false, updatable = false) @ManyToOne(optional = false) private Notify notify; @JoinColumn(name = "user_id", referencedColumnName = "id", insertable = false, updatable = false) @ManyToOne(optional = false) private User user; 

UserHasNotifyPK.java

 @Embeddable public class UserHasNotifyPK implements Serializable { @Basic(optional = false) @Column(name = "user_id") private int userId; @Basic(optional = false) @Column(name = "notify_id") private int notifyId; 

Notify.java

 @Entity @Table(name = "notify") @NamedQueries({ @NamedQuery(name = "Notify.findAll", query = "SELECT n FROM Notify n")}) public class Notify implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Basic(optional = false) @Column(name = "id") private Integer id; @Column(name = "message") private String message; @OneToMany(cascade = CascadeType.ALL, mappedBy = "notify") private Collection<UserHasNotify> userHasNotifyCollection; 

Now I would like to add a User and Notify object and create a relationship between them. So I wrote this snippet:

  User user = new User(); user.setName("John"); Notify notify = new Notify(); notify.setMessage("Hello World"); userFacade.create(user); notifyFacade.create(notify); UserHasNotify uhn = new UserHasNotify(); uhn.setNotify(notify); uhn.setUser(user); uhn.setHasRead("ok"); uhnFacade.create(uhn); 

But I get this error:

 Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'user_id' cannot be null Error Code: 1048 Call: INSERT INTO user_has_notify (has_read, user_id, notify_id) VALUES (?, ?, ?) bind => [3 parameters bound] Query: InsertObjectQuery(com.test.entity.UserHasNotify[ userHasNotifyPK=null ]) 

Why???????????

+4
source share
1 answer

The cause of the error may be remote communication. The fact that you use facades implies that you communicate with your backend remotely.

This means that the user and notify that you install on the uhn instance uhn sent to be stored on the remote system, while local instances never receive the generated identifiers.

To check and fix this, you can expand your example:

After saving user and notify extract them from the backend. This should return stored instances with existing identifiers. You can then use them to store your uhn relationship.

EDIT : I missed the fact that UserHasNotify is a state-related relationship with a built-in Id. In the code, you never set this identifier, so the provider skips it.

In this case, I would recommend using IdClass instead of embededd Id - the mapping is more readable, so you probably would not match the user and notify twice - once in the built-in PC and again in essence;)

Here's what it looks like:

 public class UserHasNotifyPK implements Serializable { private Notify notify; private User user; ... } 

.

 @Entity @Table(name = "user_has_notify") @IdClass(UserHasNotifyPK.class) @NamedQueries({ @NamedQuery(name = "UserHasNotify.findAll", query = "SELECT u FROM UserHasNotify u")}) public class UserHasNotify implements Serializable { private static final long serialVersionUID = 1L; @Column(name = "has_read") private String hasRead; @Id @JoinColumn(name = "notify_id", referencedColumnName = "id", insertable = false, updatable = false) @ManyToOne(optional = false) private Notify notify; @Id @JoinColumn(name = "user_id", referencedColumnName = "id", insertable = false, updatable = false) @ManyToOne(optional = false) private User user; 

Then you can try the same test again.

0
source

All Articles