【问题标题】:Hibernate 5 Bytecode Enhancement Association Management works just in one directionHibernate 5 字节码增强关联管理仅在一个方向上工作
【发布时间】:2016-10-23 14:34:47
【问题描述】:

我有 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 案例中,关联管理不起作用?我做错了什么?

【问题讨论】:

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


    【解决方案1】:

    在单元测试中,类可能没有得到增强,尤其是当您通过 IDE 运行它们时。

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

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

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

    反正我觉得这个功能真的没必要。 Syncing both ends of the associations is the way to go,它只需要你提供一个 addChild 和 removeChild 方法。

    【讨论】:

    • 我尝试过使用简单的 main() 方法,而不是通过测试。行为是一样的。
    • 此外,如果没有增强类,第二次测试将无法成功通过。因此它们得到了增强,因为当我检查对象时,它们具有特定的字节码 tracking 字段
    • 很高兴知道。在这种情况下,打开一个 Jira 问题并附加您的测试用例。我不确定此功能是否适用于儿童端,因此最好打开问题。
    • 我猜是这样,因为在用户指南中准确定义了在我的测试中失败的场景。我将打开 Jira 问题。感谢您的快速回答:)
    • @VladMihalcea 你能详细说明为什么你从不推广字节码增强功能吗?我无法在你的书中或你的博客上找到解释。我认为双向关联管理非常有用,因为它允许我编写/维护更少的代码。这可能与编写 getter/setter 或使用 lombok 类似。
    【解决方案2】:

    追踪 Andrei 的 JIRA 问题我了解到:

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

    所以,而不是:

    customer.getInventories().add( customerInventory );
    

    需要调用setter:

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

    【讨论】:

    猜你喜欢
    • 2019-12-16
    • 1970-01-01
    • 2018-08-08
    • 2023-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-03
    • 1970-01-01
    相关资源
    最近更新 更多