Hibernate 5 Bytecode Enhancement Association Management 只在一个方向上工作
Hibernate 5 Bytecode Enhancement Association Management works just in one direction
我有 2 个这样映射的 JPA 实体:
@MappedSuperclass
public class AbstractEntity {
private static final String INCREMENT_STRATEGY = "increment";
private static final String INCREMENT_ID_GENERATOR_NAME = "INCREMENT_ID_GENERATOR";
@Id
@GenericGenerator(name = INCREMENT_ID_GENERATOR_NAME, strategy = INCREMENT_STRATEGY)
@GeneratedValue(generator = INCREMENT_ID_GENERATOR_NAME)
private Long id;
public AbstractEntity() {
super();
}
public Long getId() {
return id;
}
}
@Entity
public class Department extends AbstractEntity{
@OneToMany(cascade = CascadeType.ALL, mappedBy = "department")
private List<Employee> employees = new ArrayList<Employee>();
public void setEmployees(List<Employee> employees) {
this.employees = employees;
}
public List<Employee> getEmployees() {
return employees;
}
}
@Entity
public class Employee extends AbstractEntity {
@ManyToOne(optional = true, cascade= CascadeType.ALL)
@JoinColumn(name = "DEPARTMENT_ID")
private Department department;
public void setDepartment(Department department) {
this.department = department;
}
public Department getDepartment() {
return department;
}
}
所有 类 都是 byte-code 使用 hibernate 增强 maven 插件增强的:
<build>
<plugins>
<plugin>
<groupId>org.hibernate.orm.tooling</groupId>
<artifactId>hibernate-enhance-maven-plugin</artifactId>
<version>5.2.2.Final</version>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.2.2.Final</version>
</dependency>
</dependencies>
<configuration>
<enableDirtyTracking>true</enableDirtyTracking>
<enableLazyInitialization>true</enableLazyInitialization>
<enableAssociationManagement>true</enableAssociationManagement>
</configuration>
</plugin>
</plugins>
</build>
我 运行 进行了两次测试,以验证增强的 类 是否正常工作:
@Test
public void test1() {
Department department = new Department();
Employee employee = new Employee();
department.getEmployees().add(employee);
assertThat(employee.getDepartment(), is(not(nullValue())));
}
@Test
public void test2() {
Department department = new Department();
Employee employee = new Employee();
employee.setDepartment(department);
assertThat(department.getEmployees().size(), is(1));
assertThat(department.getEmployees().get(0), is(employee));
}
只有第二个测试成功通过,因此当通过 parent 的集合操作关联时,child 的 parent 字段不会更新,而在 Hibernate ORM 5.2.3.Final User Guide 表示
Bytecode-enhanced bi-directional association management makes that first example work by managing the "other side" of a bi-directional association whenever one side is manipulated.
引用的“第一个例子”是
Example 204. Incorrect normal Java usage
为什么在我的 test1 案例中关联管理不起作用?我做错了什么?
在单元测试中,可能会发生 类 没有得到增强的情况,尤其是当您通过 IDE.
运行 它们时
确保增强的 类 包含在您导入到进行测试的项目中的不同模块中。
或者您可以 运行 增强过程,验证 类 是否增强,然后才 运行 单元测试。
总而言之,我猜您可能 运行正在使用实体的未增强版本 类。
总之,我认为这个功能不是很有必要。 Syncing both ends of the associations is the way to go,只需要你提供一个addChild和removeChild方法即可。
追踪 Andrei 的 JIRA 问题我了解到:
to trigger the association management, at some point there has to be a
change in the *ToMany field, even if it's with the same collection.
The collection itself is not tracked for changes.
所以,而不是:
customer.getInventories().add( customerInventory );
需要调用 setter:
Collection<CustumerInventory> inventories = customer.getInventories();
inventories.add( customerInventory );
custumer.setInventories( inventories );
我有 2 个这样映射的 JPA 实体:
@MappedSuperclass
public class AbstractEntity {
private static final String INCREMENT_STRATEGY = "increment";
private static final String INCREMENT_ID_GENERATOR_NAME = "INCREMENT_ID_GENERATOR";
@Id
@GenericGenerator(name = INCREMENT_ID_GENERATOR_NAME, strategy = INCREMENT_STRATEGY)
@GeneratedValue(generator = INCREMENT_ID_GENERATOR_NAME)
private Long id;
public AbstractEntity() {
super();
}
public Long getId() {
return id;
}
}
@Entity
public class Department extends AbstractEntity{
@OneToMany(cascade = CascadeType.ALL, mappedBy = "department")
private List<Employee> employees = new ArrayList<Employee>();
public void setEmployees(List<Employee> employees) {
this.employees = employees;
}
public List<Employee> getEmployees() {
return employees;
}
}
@Entity
public class Employee extends AbstractEntity {
@ManyToOne(optional = true, cascade= CascadeType.ALL)
@JoinColumn(name = "DEPARTMENT_ID")
private Department department;
public void setDepartment(Department department) {
this.department = department;
}
public Department getDepartment() {
return department;
}
}
所有 类 都是 byte-code 使用 hibernate 增强 maven 插件增强的:
<build>
<plugins>
<plugin>
<groupId>org.hibernate.orm.tooling</groupId>
<artifactId>hibernate-enhance-maven-plugin</artifactId>
<version>5.2.2.Final</version>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.2.2.Final</version>
</dependency>
</dependencies>
<configuration>
<enableDirtyTracking>true</enableDirtyTracking>
<enableLazyInitialization>true</enableLazyInitialization>
<enableAssociationManagement>true</enableAssociationManagement>
</configuration>
</plugin>
</plugins>
</build>
我 运行 进行了两次测试,以验证增强的 类 是否正常工作:
@Test
public void test1() {
Department department = new Department();
Employee employee = new Employee();
department.getEmployees().add(employee);
assertThat(employee.getDepartment(), is(not(nullValue())));
}
@Test
public void test2() {
Department department = new Department();
Employee employee = new Employee();
employee.setDepartment(department);
assertThat(department.getEmployees().size(), is(1));
assertThat(department.getEmployees().get(0), is(employee));
}
只有第二个测试成功通过,因此当通过 parent 的集合操作关联时,child 的 parent 字段不会更新,而在 Hibernate ORM 5.2.3.Final User Guide 表示
Bytecode-enhanced bi-directional association management makes that first example work by managing the "other side" of a bi-directional association whenever one side is manipulated.
引用的“第一个例子”是
Example 204. Incorrect normal Java usage
为什么在我的 test1 案例中关联管理不起作用?我做错了什么?
在单元测试中,可能会发生 类 没有得到增强的情况,尤其是当您通过 IDE.
运行 它们时确保增强的 类 包含在您导入到进行测试的项目中的不同模块中。
或者您可以 运行 增强过程,验证 类 是否增强,然后才 运行 单元测试。
总而言之,我猜您可能 运行正在使用实体的未增强版本 类。
总之,我认为这个功能不是很有必要。 Syncing both ends of the associations is the way to go,只需要你提供一个addChild和removeChild方法即可。
追踪 Andrei 的 JIRA 问题我了解到:
to trigger the association management, at some point there has to be a change in the *ToMany field, even if it's with the same collection. The collection itself is not tracked for changes.
所以,而不是:
customer.getInventories().add( customerInventory );
需要调用 setter:
Collection<CustumerInventory> inventories = customer.getInventories();
inventories.add( customerInventory );
custumer.setInventories( inventories );