Hibernate 5字节码增强协会管理只在一个方向上工作

时间:2016-10-23 14:34:47

标签: java hibernate maven one-to-many bytecode

我有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;
    }

}

所有类都使用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));
}

只有第二个测试成功通过,因此当通过父集合操纵关联时,子节点的父节点不会更新,而在Hibernate ORM 5.2.3.Final User Guide中则表示

  

字节码增强的双向关联管理使得第一个示例通过在操纵一侧时管理双向关联的“另一侧”来工作。

引用“第一个例子”的地方是

  

示例204.正常的Java使用不正确

为什么在我的test1案例中,关联管理不起作用?我做错了什么?

2 个答案:

答案 0 :(得分:2)

在单元测试中,可能会发生类未被增强的情况,尤其是当您通过IDE运行它们时。

确保增强的类包含在您进行测试的项目中导入的其他模块中。

或者您可以运行增强过程,验证类是否已增强,然后才运行单元测试。

总而言之,我猜你可能正在运行实体类的非增强版本。

无论如何,我认为这个功能并不是必需的。 Syncing both ends of the associations is the way to go,它只需要您提供addChild和removeChild方法。

答案 1 :(得分:-1)

追踪安德烈的JIRA问题我了解到:

  

触发关联管理,在某些时候必须有一个   更改* ToMany字段,即使它具有相同的集合。   不会跟踪集合本身的更改。

所以,而不是:

customer.getInventories().add( customerInventory );

需要调用setter:

Collection<CustumerInventory> inventories = customer.getInventories();
inventories.add( customerInventory ); 
custumer.setInventories( inventories );