简体   繁体   English

Hibernate 5字节码增强关联管理仅在一个方向上工作

[英]Hibernate 5 Bytecode Enhancement Association Management works just in one direction

I have 2 JPA Entities mapped like this : 我有两个这样映射的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;
    }

}

All classes are byte-code enhanced using hibernate enhance maven plugin : 所有类都使用休眠增强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>

I run two tests in order to verify that enhanced classes works properly : 我运行两个测试以验证增强类是否正常工作:

@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));
}

Only the second test passes successfully, hence while the association is manipulated through parent's collection, the child's parent field is not updated, whereas in Hibernate ORM 5.2.3.Final User Guide is said 只有第二次测试成功通过,因此在通过父级集合操作关联的同时,不会更新子级的父级字段,而在《 Hibernate ORM 5.2.3》中则是《 最终用户指南》。

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. 字节码增强的双向关联管理通过操纵双向关联的“另一侧”来管理第一个示例。

Where referenced "first example" is 所引用的“第一个示例”是

Example 204. Incorrect normal Java usage 例子204.普通Java用法不正确

Why in my test1 case the association management doesn't work ? 为什么在我的test1案例中,关联管理不起作用? What did I do wrong? 我做错了什么?

In unit tests, it might happen that the classes haven't been enhanced, especially when you run them through an IDE. 在单元测试中,可能会发生未增强类的情况,尤其是在通过IDE运行它们时。

Make sure the enhanced classes are contained in a different module that you import in the project where you do the testing. 确保增强的类包含在您在进行测试的项目中导入的其他模块中。

Or you can run the enhance process, verify the classes are enhanced and only then run the unit test. 或者,您可以运行增强过程,验证类是否得到增强,然后才运行单元测试。

All in all, I guess you might be running the un-enhanced version of your entity classes. 总而言之,我想您可能正在运行实体类的未增强版本。

Anyway, I don't think that this feature is really necessary. 无论如何,我认为此功能并不是真正必要的。 Syncing both ends of the associations is the way to go , and it only requires you to provide an addChild and removeChild methods. 同步关联的两端都是一种方法 ,它仅需要您提供addChild和removeChild方法。

Tracking down Andrei's JIRA issue I learned that: 追踪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. 要触发关联管理,有时必须更改* ToMany字段,即使该字段具有相同的集合。 The collection itself is not tracked for changes. 集合本身不会跟踪更改。

So, instead of: 因此,代替:

customer.getInventories().add( customerInventory );

It's required a call to the setter: 需要调用设置器:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM