【问题标题】:How to prevent Hibernate from calling default constructor when resolving the unsaved-value解决未保存值时如何防止 Hibernate 调用默认构造函数
【发布时间】:2016-01-26 13:26:36
【问题描述】:

我正在使用 Hibernate 4.1.6.Final 并注意到,在启动过程中,每个实体的构造函数都会被调用。 EntityManager 实例化每个标有@Entity 的类作为测试,以获得unsavedValue 标识符。我正在使用没有映射文件的 Hibernate,只使用注释。是否可以防止休眠一次实例化每个实体,可能在注释中使用预定义的标识符?

示例: 一个简单的类,用作使用休眠保存的实体。

@Entity
public class SimpleEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id = null;

    public SimpleEntity() {
        System.out.println("called constructor");
    }
}

调用创建一个EntityManagerFactory,在其中构造对象:

public static EntityManagerFactory getEntityManagerFactory() {
    EntityManagerFactory emf =  Persistence.createEntityManagerFactory("hsqldb-ds");
    return emf;
}

现在调用:

EntityManagerUtil.getEntityManagerFactory().createEntityManager();

已经生成控制台输出: 调用构造函数

【问题讨论】:

  • 为什么这很重要?除非您在构造函数中发生了一些事情,否则我看不出它会产生什么负面影响。
  • 可能不应该出现在实体构造函数中的东西。

标签: java hibernate jpa orm hibernate-mapping


【解决方案1】:

没有理由担心在启动时会创建这些对象。创建一个对象大约需要 100 ns,所以如果你有 100 个实体(合理的中型企业应用程序),这个过程仍然需要大约 10 微秒(0.01 ms)。 与运行一个简单的数据库查询(例如 0.1-10 毫秒)或更复杂的查询(例如 100-1000 毫秒)所需的时间相比,这微不足道。

唯一的解决方法是:

  1. 您切换到分配的标识符:

    @Id
    private Long id = null;
    
  2. 您使用 HBM XML 映射(没有等效的 unsaved-value 注释):

    <id name="id" type="Long" column="id" unsaved-value="null">
        <generator class="native"/>
    </id>
    

【讨论】:

  • 您的第一个答案适用于我的情况,当然现在需要手动设置id。问题更多是关于这种意外行为本身,因为它让我感到惊讶。
  • Hibernate 在决定一个实体是瞬态的还是分离的时必须知道要比较的值。如果没有unsaved-value,它将需要一个 SELECT 查询来了解内存中托管实体是否存在镜像表行。
猜你喜欢
  • 2016-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多