java - 使用 EntityManager 指定列两次

标签 java hibernate jpa orm

我试图保留一个具有复合主键的实体,但出现错误:

12:59:48,221 WARN  [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (default task-56) SQL Error: 1110, SQLState: 42000

12:59:48,221 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (default task-56) Column 'SENDERID' specified twice

我正在使用 EntityManager,所以我不确定 'SENDERID' 在哪里指定了两次?

这是所有相关的类:

网络服务:

@Path("friendservice")
public class FriendWebService {

    @EJB
    private FriendrequestFacade friendRequestFacade;

    @GET
    @Path("friendrequest")
    @Produces(MediaType.TEXT_PLAIN)
    public String insertFriendRequest(
                    @Context HttpServletRequest request){
        String result = "false";
        User user = (User) request.getSession().getAttribute("user");
        User otherUser = (User) request.getSession().getAttribute("profileuser");
        if((user != null) && (otherUser != null)){
            if(user.getId() != otherUser.getId()){
                System.out.println("Both users are alive.");
                if(friendRequestFacade.insertFriendRequest(user, otherUser))
                    result = "true";
            }
        }
        return result;
    }           
}

外观:

@Stateless
public class FriendrequestFacade extends AbstractFacade<Friendrequest> {
    @PersistenceContext(unitName = "FakebookPU")
    private EntityManager em;

    @Override
    protected EntityManager getEntityManager() {
        return em;
    }

    public FriendrequestFacade() {
        super(Friendrequest.class);
    }

    public boolean insertFriendRequest(User user, User otherUser){
        Friendrequest fr = new Friendrequest();
        FriendrequestPK frPK = new FriendrequestPK();
        frPK.setSenderid(user.getId());
        frPK.setReceiverid(otherUser.getId());
        fr.setId(frPK);
        em.clear();
        em.persist(fr);
        return true;                
    }
}

实体:

@Entity
@XmlRootElement
@Table(name="FRIENDREQUEST")
@NamedQuery(name="Friendrequest.findAll", query="SELECT f FROM Friendrequest f")
public class Friendrequest implements Serializable {
    private static final long serialVersionUID = 1L;

    @EmbeddedId
    private FriendrequestPK id;

    @Temporal(TemporalType.TIMESTAMP)
    private Date senddate;

    //bi-directional many-to-one association to User
    @ManyToOne
    @JoinColumn(name="SENDERID")
    private User user1;

    //bi-directional many-to-one association to User
    @ManyToOne
    @JoinColumn(name="RECEIVERID")
    private User user2;

    public Friendrequest() {}

    public FriendrequestPK getId() {
        return this.id;
    }

    public void setId(FriendrequestPK id) {
        this.id = id;
    }

    public Date getSenddate() {
        return this.senddate;
    }

    public void setSenddate(Date senddate) {
        this.senddate = senddate;
    }

    public User getUser1() {
        return this.user1;
    }

    public void setUser1(User user1) {
        this.user1 = user1;
    }

    public User getUser2() {
        return this.user2;
    }

    public void setUser2(User user2) {
        this.user2 = user2;
    }

}

复合键:

@Embeddable
public class FriendrequestPK implements Serializable {
    //default serial version id, required for serializable classes.
    private static final long serialVersionUID = 1L;

    @Column(insertable=false, updatable=false)
    private int senderid;

    @Column(insertable=false, updatable=false)
    private int receiverid;

    public FriendrequestPK() {}

    public FriendrequestPK(int senderid, int receiverid){
        this.senderid = senderid;
        this.receiverid = receiverid;
    }

    public int getSenderid() {
        return this.senderid;
    }

    public void setSenderid(int senderid) {
        this.senderid = senderid;
    }

    public int getReceiverid() {
        return this.receiverid;
    }

    public void setReceiverid(int receiverid) {
        this.receiverid = receiverid;
    }
}

我做错了什么?

最佳答案

首先请让我澄清一下,我很少使用@EmbeddedId,所以我可能会遗漏一些东西。也就是说,错误告诉您 SENDERID 列被指定了两次:第一次在您的实体中,然后在复合键中。 RECEIVERID 也可能发生同样的情况。

实体

public class Friendrequest implements Serializable {
    ...
    @EmbeddedId
    private FriendrequestPK id;

    @ManyToOne
    @JoinColumn(name="SENDERID") // Column = SENDERID
    private User user1;

    @ManyToOne
    @JoinColumn(name="RECEIVERID") // Column = RECEIVERID
    private User user2;
    ...
}

复合键

public class FriendrequestPK implements Serializable {
    ...
    @Column(insertable=false, updatable=false)
    private int senderid; // Column = SENDERID

    @Column(insertable=false, updatable=false)
    private int receiverid; // Column = RECEIVERID
    ...
}

根据Mapping identifier properties Hibernate Annotations 中的部分引用指南,实体映射应该使用@MapsId注释完成:

public class Friendrequest implements Serializable {
    ...
    @EmbeddedId
    private FriendrequestPK id;

    @MapsId("senderid") // senderid = Field in FriendrequestPK class
    @ManyToOne
    private User user1;

    @MapsId("receiverid") // receiverid = Field in FriendrequestPK class
    @ManyToOne
    private User user2;
    ...
}

关于java - 使用 EntityManager 指定列两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25808167/

相关文章:

java - 如何使用 Hibernate 将图像流式传输到数据库中?

java - 批量插入现有数据 : Preventing JPA to do a select before every insert

java - Gradle 文件系统。使用 '/' 或 File.separator?

java - 为什么我们在 Hibernate 中使用 @Embeddable

java - 从属性文件加载数据以供 Liquibase 在 Maven 构建中使用

java - 如何将 native 查询结果映射到自定义类对象?

java - JPA双向@ManyToMany关系: Assignment causes two inserts

java - 使用仅具有 id 值的实体保存外键

java - 在 Java 或 Perl 中创建随机 XML 条目

java - 我们如何实现车库门跟踪其最后移动方向?