抛出空指针异常的JPA管理实体

时间:2017-05-29 07:48:06

标签: hibernate jpa nullpointerexception thread-safety

我在我的一个项目中使用JPA 2.0和SpringBoot。由于应用程序需要大量只读查询,因此我决定将entityManager标记为的单例(Autowired)类 的 @PersistenceContext(类型= PersistenceContextType.EXTENDED)即可。

扩展实体管理器的这个实例又被众多DAO(可能在多个线程中)用于其只读请求。由于实体曾经在扩展的持久化上下文中,因此对实体进一步详细说明(如果你愿意的话,保留)的调用从未给出LazyInitializationException。此外,由于实体一旦加载,总是存在于扩展持久化上下文的活动内存中,用于获得优异的性能。

但是,随着时间的推移,我偶尔会在访问其中一个托管实体的某个字段时开始获取 NullPointerException 。这种行为是不确定的。

        // .. earlier code skipped for brevity
        Child child = refNode.getFirstChild();

        if (child != null) {
            // Print confirms that the object is managed. In fact, earlier merely 
            // inserting print statement would dissolve the error.
            System.out.printf ("Child ID = %s %s\n", child.getChildID(), childDAO.getContext(child));

            // NPE while accessing latestVersion attribute of 'Child'.
            // Values does exist in DB. 
            Unode un = child.getLatestVersion().getuNode();
            return un;
        }

儿童的相关部分'实体如下:

    public class Child implements Serializable { 
        private static final long serialVersionUID = 1L;

        @Id
        @GeneratedValue(strategy=GenerationType.AUTO)
        private int childID;
        ...
        @ManyToOne(cascade={CascadeType.ALL})
        @JoinColumn(name="latestVersionID")
        private Version latestVersion;

是的,我也非常慷慨地收到了以下错误。

    HHH000099: an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session): org.hibernate.AssertionFailure: possible non-threadsafe access to the session

最近我也得到了ConcurrentModificationException',不安全的线程访问,以及代码中所有类型的干净部分中的类似错误。我也尝试在所有访问中使用synchronized(互斥)来使我的扩展上下文实体管理器线程安全,但没有帮助。

我最担心的是一个托管实体(在扩展上下文中),提供null指向异常。虽然例外似乎是非确定性的,但它们似乎往往集中在“儿童”的地方。或者' Child.LatestVersion'被访问。

我试过,懒惰加载,急切加载等,但没有用。我的理解(到目前为止)是前向实体被急切地加载,反向实体被懒惰地加载,并且在管理实体时(在任何上下文中 - 扩展或事务性)从不出现空指向异常。

真诚地感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

答案很简单:EntityManager不是线程安全的。参见例如在这里:https://docs.jboss.org/hibernate/entitymanager/3.6/reference/en/html/transactions.html#transactions-basics-issues

你应该做的是你应该停止尝试重复使用它。 EntityManager与(EntityManagerFactory相比)创建成本低廉。