EntityManager.find 对象包含 2 个 id 作为主键的行为

Posted

技术标签:

【中文标题】EntityManager.find 对象包含 2 个 id 作为主键的行为【英文标题】:EntityManager.find behavior with an object containing 2 id as primary key 【发布时间】:2017-01-23 10:53:09 【问题描述】:

我开始涉足 Java 世界,但我很难理解这一点。

我正在使用 JPA 通过 JPQL 与我的数据库进行交互。

我有一个像这样的持久类:

@Entity
@Table(name="C_A_T")
@NamedQuery(name="CAT.findAll", query="SELECT c FROM CAT c")
public class CAT implements Serializable 
    private static final long serialVersionUID = 1L;
    @EmbeddedId
    private CATPK id;
    private String offer;
    @Temporal(TemporalType.DATE)
    @Column(name="MODIF_DATE")
    private Date modifDate;


    public CAT() 
    public CATPK getId() return id;
    public void setId(CATPK id) this.id = id;
    public String getOffer() return offer;
    public void setOffer(String offer) this.offer = offer; 
    public Date getModifDate() return modifDate;
    public void setModifDate(Date modifDate) this.modifDate= modifDate;
    /* ... */

CATPK 类表示CAT 实例的主键:

@Embeddable
public class CATPKimplements Serializable 
    //default serial version id, required for serializable classes.
    private static final long serialVersionUID = 1L;
    @Column(name="ID_CAT")
    private String idCAT;
    @Column(name="ID_DEMANDE")
    private String idDemande;

    public CATPK() 
    public String getIdCAT() return this.idCAT;
    public void setIdCAT(String idCAT) this.idCat= idCat;
    public String getIdDemande() return this.idDemande;
    public void setIdDemande(String idDemande) this.idDemande = idDemande;
    /* ...*/

所以基本上,主键由 2 个不同的 ID 组成。

现在,有时,在我的数据库中插入 CAT 之前,我检查了它是否已经在 C_A_T 表中:

EntityManagerFactory emf = Persistence.createEntityManagerFactory("cie");
em = emf.createEntityManager();
em.getTransaction().begin();
// inCAT is an instance of CAT on which there is a complete primary key CATPK (made of 2 id)
CAT CATinDB = em.find( CAT.class, inCAT.getId() );
if (null == CATinDB)
  em.persist(inCAT); // CAT created
em.getTransaction().commit();
em.close();

现在,问题是 em.find( CAT.class, inCAT.getId() ); 行没有返回 null

例如,当我实际上没有正确的行时,CATinDB 可以包含一行 idCATidDemande

那么find 是否会认为它仅与catPK 匹配的一个 id 被发现?

最后,我换了一行:

if (null == CATinDB)

进入:

if (null == CATinDB || CATinDB.getId().getIdCAT() != inCAT.getId().getIdCAT() || CATinDB.getId().getIdDemande() != inCAT.getId().getIdDemande())

当我没有与 2 id 匹配的记录时,我不确定为什么 find 没有返回 null。

【问题讨论】:

您可以在此处查看 JPA 提供程序日志并查看调用的 SQL。 我该怎么做?我正在使用 IntelliJ。我有一个 persistence.xml 文件,但我不知道从那里去哪里 persistence.xml 通常指定 JPA 提供程序。无论是否,您都可以轻松地从 CLASSPATH 和“emf”实例的类中确定您使用的是哪一个。因此,您查看该提供程序的文档,然后查看日志。又名“调试” 这篇文章可以帮助解释如何实现它。 ***.com/questions/17042987/… 【参考方案1】:

实际上,我只需要重新启动我的 weblogic 服务器。当我更新数据库时,看起来数据源没有动态更新。

【讨论】:

以上是关于EntityManager.find 对象包含 2 个 id 作为主键的行为的主要内容,如果未能解决你的问题,请参考以下文章

Session.get() 和 EntityManager.find() Hibernate 有啥区别

EntityManager.find() 和 EntityManger.getReference() 有啥区别?

EntityManager.find(id) 会执行恶意攻击吗?

JPA学习笔记(11)——使用二级缓存

Eclipselink 未检测到脏实体

如何查看 JPA 发出的 SQL 查询?