JPA简单多到多用的EclipseLink(JPA simple many-to-many with

2019-07-19 13:19发布

我有这个ER图:

这被翻译成这些类:

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;

现在,我想补充一个实体的用户,并通知并创建它们之间的关系。 所以我写了这个片断:

        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);

但我收到此错误:

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 ])

为什么???????????

Answer 1:

的原因的错误可以位于远程communicaton。 您正在使用外墙的事实意味着,你与你的后端远程通信。

这将意味着usernotify你的设置情况uhn实例发送远程系统上要坚持,而当地的情况从来没有收到生成的ID。

要验证和解决这个问题,你可以扩展你的例子:

保存后, usernotify ,从后端获取它们。 这应返回持久化的情况下,与现有的IDS。 然后,你可以用它们来存储您的uhn关系。

编辑 :我已经错过了一个事实,即UserHasNotify是一个embededd ID的状态关系。 在代码中你从来没有设置这个ID,所以提供商怀念它。

对于这种情况,我会建议使用IdClass代替embededd Id的-映射更具可读性,所以你很可能不会映射到UserNotify相关两次-在实体在嵌入式PK一次又一次;)

下面是它会是什么样子:

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;

然后,您可以再次尝试相同的测试。



文章来源: JPA simple many-to-many with eclipselink