我有几个与@JoinTable具有双向@ OneToMany关系的实体。除了将大量数据集插入数据库的性能之外,功能正常。 我发现在这种情况下,Hibernate并没有对所有实体使用批处理。 Hibernate使用批处理为父实体,但不为子实例。它使用批处理将所有父数据集插入到数据库中,然后生成子数据集,然后生成关联的mappingtable-dataset,然后生成下一个子数据集,然后生成关联的mappingtable-dataset等,所有这些都是单个数据集语句。
当我将@ OneToMany-Relation for test更改为@ ManyToMany-Relation时,批处理将用于所有数据集,首先是所有父项,然后是所有子项,然后是所有映射,并且性能会急剧增加。 同样在单向OneToMany-Relation批处理上工作正常。
有人可以解释一下,如何使用@JoinTable配置双向@ OneToMany关系,以便Hibernate也为子节点使用批量处理?
重现的简单示例: 家长A:
package com.flobuc;
import javax.persistence.*;
import java.util.Collection;
@Entity
@Table(name = "A")
public class A {
private String id;
private String name;
private Collection<B> bs;
@Id
@Column(name = "ID")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Basic
@Column(name = "NAME")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@OneToMany(cascade = CascadeType.ALL, mappedBy = "a")
public Collection<B> getBs() {
return bs;
}
public void setBs(Collection<B> bs) {
this.bs = bs;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
A a = (A) o;
if (id != null ? !id.equals(a.id) : a.id != null) return false;
return name != null ? name.equals(a.name) : a.name == null;
}
@Override
public int hashCode() {
int result = id != null ? id.hashCode() : 0;
result = 31 * result + (name != null ? name.hashCode() : 0);
return result;
}
}
孩子B:
package com.flobuc;
import javax.persistence.*;
@Entity
@Table(name = "B")
public class B {
private String id;
private String name;
private A a;
@Id
@Column(name = "ID")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Basic
@Column(name = "NAME")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@ManyToOne
@JoinTable(
name="A2B",
joinColumns = {@JoinColumn(name = "B_ID", referencedColumnName = "ID", nullable = false)},
inverseJoinColumns={@JoinColumn(name = "A_ID", referencedColumnName = "ID", nullable = false)})
public A getA() {
return a;
}
public void setA(A a) {
this.a = a;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
B b = (B) o;
if (id != null ? !id.equals(b.id) : b.id != null) return false;
return name != null ? name.equals(b.name) : b.name == null;
}
@Override
public int hashCode() {
int result = id != null ? id.hashCode() : 0;
result = 31 * result + (name != null ? name.hashCode() : 0);
return result;
}
}
生成实体并坚持:
List<A> as = new ArrayList<>();
for (int i = 0; i < 100 ; i++) {
A a = new A();
a.setId("ID-A-" + i);
a.setName("Name ID-" + i);
a.setBs(new HashSet<>());
for (int j = 0; j < 50 ; j++) {
B b =new B();
b.setId("ID-B-" + j + "ID-A-" + i);
b.setName("Name ID-" + j + " Parent " + i);
b.setA(a);
a.getBs().add(b);
}
as.add(a);
}
for(A a : as){
em.persist(a);
}
的persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="TimetablePU" transaction-type="JTA">
<jta-data-source>java:/TimetableDS</jta-data-source>
<class>com.atron.atries.rx.asdm.dao.entity.netex.A</class>
<class>com.atron.atries.rx.asdm.dao.entity.netex.B</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
<property name="hibernate.jdbc.batch_size" value="10"/>
<property name="hibernate.order_inserts" value="true"/>
<property name="hibernate.order_updates" value="true"/>
<property name="hibernate.jdbc.batch_versioned_data" value="true"/>
</properties>
</persistence-unit>
</persistence>
环境:WildFly 10.1,Hibernate 5.0.1