Hibernate合并分离对象后,非空集合始终标记为脏

时间:2014-12-20 05:46:12

标签: java hibernate

我并不期待这种行为,也不确定这是一个错误还是设计错误。

我们有一个带有子对象列表的父对象。它是使用连接表的单向关系。如果客户端请求父对象合并,则Hibernate 会增加父对象的版本,即使它的所有细节都没有更改。我不希望父对象版本改变,因为从逻辑上讲,父对象完全相同。有人有解释吗?

注1:由于集合在flush中被标记为脏,但如果集合为空或父对象不包含集合,则不会发生这种情况

p>

注2:非常类似https://hibernate.atlassian.net/browse/HHH-3007由于不活动而自动关闭

注3:使用Hibernate 4.3.7.Final,但在Hibernate 3中测试了相同的行为

测试重现

@Test
public void testCreateAndUpdate() throws Exception {

    // POST from client - note: deptartment object containing a single empty employee 
    String jsonFromClient = "{\"employees\":[{}]}";
    Department department = mapper.readValue(jsonFromClient, Department.class);

    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();
    session.persist(department);
    tx.commit();

    // simulates sending it back to client
    String jsonToClient = mapper.writeValueAsString(department);
    System.out.println(jsonToClient);   // {"id":1,"version":0,"employees":[{"id":1,"version":0}]}

    // PUT from client, but nothing has actually changed
    jsonFromClient = jsonToClient;
    department = mapper.readValue(jsonFromClient, Department.class);

    // new session emulates the client updating the Department
    session = sessionFactory.openSession();
    tx = session.beginTransaction();
    department = (Department) session.merge(department);
    tx.commit();

    // NOTE: PARENT VERSION INCREMENTED!!
    jsonToClient = mapper.writeValueAsString(department);
    System.out.println(jsonToClient);  // {"id":1,"version":1,"employees":[{"id":1,"version":0}]}

}

Department.java

@Entity
public class Department {
private Long id;
private Long version;
private List<Employee> employees = new ArrayList<>();


@Id
@GeneratedValue
public Long getId() { return id; }

public void setId(Long id) { this.id = id; }

@Version
public Long getVersion() { return version; }

public void setVersion(Long version) { this.version = version; }

@OneToMany(cascade = CascadeType.ALL)
@JoinTable(name="DEPARTMENT_EMPLOYEE", joinColumns = @JoinColumn( name="DEPARTMENT_ID"), inverseJoinColumns = @JoinColumn( name="EMPLOYEE_ID"))
public List<Employee> getEmployees() { return employees; }

public void setEmployees(List<Employee> employees) { this.employees = employees; }

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof Department)) return false;

    Department that = (Department) o;

    //if (employees != null ? !employees.equals(that.employees) : that.employees != null) return false;
    if (!id.equals(that.id)) return false;
    if (!version.equals(that.version)) return false;

    return true;
}

@Override
public int hashCode() {
    int result = id.hashCode();
    result = 31 * result + version.hashCode();
    result = 31 * result + (employees != null ? employees.hashCode() : 0);
    return result;
}

}

Employee.java

@Entity
public class Employee {

private Long id;
private Long version;


@Id
@GeneratedValue
public Long getId() { return id; }

public void setId(Long id) { this.id = id; }

@Version
public Long getVersion() { return version; }

public void setVersion(Long version) { this.version = version; }

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof Employee)) return false;

    Employee employee = (Employee) o;

    if (!id.equals(employee.id)) return false;
    if (!version.equals(employee.version)) return false;

    return true;
}

@Override
public int hashCode() {
    int result = id.hashCode();
    result = 31 * result + version.hashCode();
    return result;
}

}

0 个答案:

没有答案