【问题标题】:What is the correct way to see if an arbitrary object is a JPA entity?查看任意对象是否为 JPA 实体的正确方法是什么?
【发布时间】:2014-01-20 18:34:18
【问题描述】:

javax.persistence.EntityManager#contains(Object) method's documentation 说(部分):

检查实例是否是属于当前持久性上下文的托管实体实例。 投掷: IllegalArgumentException - 如果不是实体

JPA 2.1 specification 的第 3.1.1 节说:

EntityManager接口的方法[例如contains(Object)]而不是LockTimeoutException的方法抛出的运行时异常[例如IllegalArgumentException]将导致当前事务被标记为回滚,如果持久性上下文是加入该交易。

那么,什么是检查任意对象(不知道它是否是实体,不知道它是否在持久化上下文中)是否既是实体又在持久化上下文中而不回滚的首选方法当前交易?

【问题讨论】:

  • 你在什么环境下:Java EE 还是 SE?如果是 EE,你用什么应用服务器不管你的上下文,你有没有试过我的代码(如果是 SE,可能会适应)?
  • GlassFish 3.1.2.2 随附的 EclipseLink。在任意非实体对象上调用 contains() 会回滚事务,除非我遗漏或混淆了某些内容。
  • 即使异常立即被捕获?你试过我的代码了吗?
  • 使用静态元模型,参见。 stackoverflow.com/questions/49307727/….

标签: jpa


【解决方案1】:

您可以在新交易中进行检查,这不会影响您当前的交易。


一些注意事项 这是您上一个问题的一个很好的例子,当我回答规范的某些部分没有正确制定时。我会给你一个例子,它没有任何问题,这与规范相矛盾(至少在带有 Hibernate 的 JBoss 7.1 中):

public class EjbServiceBean implement EjbService {

    @PersistenceContext
    private EntityManager em;

    @Override
    public void testTransaction() {

        //this code is in a transaction EJB method
        MyEntity entity = em.find(MyEntity.class, 1L);
        entity.setPeristentField("New Value");

        try {
            em.find(Class.class, 1);//should rollback the transaction
        } catch (Exception e) {
            //simply catching the Exception, so that the CMT transaction is not rolled back by the EJB container.
        }
    //but after the method returns, the entity instance is commited.
    }
}

通过这个例子,我的意思是你可以在实践中使用em.contains() 方法来检查一个类是否是一个实体类。

PS:这在 2.0 规范中也有规定。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-16
    • 2010-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-25
    • 2013-04-12
    相关资源
    最近更新 更多