在Hibernate / JPA中批量插入CollectionTable元素



我们使用Hibernate 4.2作为JPA 2.0实体的支持库。我们有一个像这样的实体:

@Entity
public class MyEntity {
    ....
    @ElementCollection
    @MapKeyColumn(name = "key")
    @Column(name = "value")
    @CollectionTable("MyEntityMap")
    private Map<String, Integer> theMap;
    ...
}

映射可能有数千个条目。我设置了hibernate.jdbc.batch_size=50,但是当我输入entityManager.persist(myEntity)时,Hibernate仍然为映射中的每个条目生成一条插入语句。

是否有一种方法可以使Hibernate在像INSERT INTO MyEntityMap () VALUES (), (), (), (), ()这样的批量插入中插入值?

我有完全相同的场景,这就是我最终做的…

在persistence.xml/等效文件

中使用以下配置
<property name="hibernate.jdbc.batch_size" value="10"/> 
<property name="hibernate.order_inserts" value="true"/> 
<property name="hibernate.order_updates" value="true"/>

你给的例子是批量插入,上面的配置所做的只是将单个插入语句作为单个批处理发送到DB,它实际上并没有重写插入到

INSERT INTO MyEntityMap () VALUES (), (), (), (), ()

和不可否认的批量插入只提供了轻微的性能改进,真正的性能改进可以从批量插入中获得。

批量插入不是ANSI SQL的特性,而是单个数据库提供程序的特性,MySQL DB连接器驱动程序提供了一个配置,可以将批量插入重写为批量插入

使用如下所示的连接字符串

jdbc.url=jdbc:mysql://localhost:3306/macula?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8&rewriteBatchedStatements=true

现在,一旦你完成了这些,如果你尝试运行应用程序,并在mysql中启用常规查询日志记录,你会看到你的插入被重写为批量插入…但你也会得到是一个BatchedTooManyRowsAffectedException:)

这是由org.hibernate.jdbc. expectations . basicexpectations . verifyoutcome()方法抛出的(第67行)

由于hibernate对重写一无所知,它无法理解更新计数,我找不到一个合理的方法来挂钩我的期望类的实现…

这是一个死胡同,我们不能在hibernate中使用rewriteBatchedStatements特性!!

好吧,除非你愿意做一个邪恶的黑客,那就是…只需将类复制粘贴到你的项目代码中,在完全相同的包层次结构下,这意味着hibernate将选择复制粘贴的类,而不是打包在hibernate jar中的类,然后只需注释掉if语句…是的,然后一切都很顺利!!

仔细考虑上面的hack;)

相关内容

  • 没有找到相关文章

最新更新