Nested derived identifies are not propperly initialized for loaded collections
-------------------------------------------------------------------------------
Key: HHH-6646
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-6646
Project: Hibernate Core
Issue Type: Bug
Components: core, query-hql, query-sql
Affects Versions: 4.0.0.CR2, 3.6.7
Environment: Hibernate 3.6.7.Final and 4.0.0.CR2 on Mac OS X 10.7.1 with HSQLDB
2.0.0
Reporter: Anton Korshunov
Priority: Critical
Attachments: jpa2-persistence.zip
Hi guys,
I've just tried to run an example from Mike Keith's Pro JPA 2 book and failed to
do so due to a possible bug in Hibernate while loading a one-to-many collection containing
entities, which primary key is a derived @Embeddable identifier, holding another (nested)
@Embeddable identifier, as some fields of such identifiers are initialized with wrong
values.
Here is what I've got:
@Embeddable
public class DeptId implements Serializable {
@Column(name = "CTRY")
private int country;
@Column(name = "NUM")
private int number;
..
}
@Embeddable
public class ProjectId implements Serializable {
@Embedded
private DeptId dept;
@Column(name = "P_NAME")
private String name;
...
}
@Entity
public class Project {
@MapsId("dept")
@ManyToOne
@JoinColumns({
@JoinColumn(name = "DEPT_NUM", referencedColumnName =
"NUM",
updatable = false, insertable = false),
@JoinColumn(name = "DEPT_CTRY", referencedColumnName =
"CTRY",
updatable = false, insertable = false)
})
private Department department;
@EmbeddedId
private ProjectId id;
...
}
@Entity
public class Department {
@EmbeddedId
private DeptId id;
@OneToMany(mappedBy = "department")
private List<Project> projects = new ArrayList<Project>();
...
public void addProject(final Project project) {
projects.add(project);
project.setDepartment(this);
}
}
And the test case:
final Department d1 = new Department(new DeptId(1, 44));
final Project p1 = new Project(new ProjectId(d1.getId(), "proj1"));
final Project p2 = new Project(new ProjectId(d1.getId(), "proj2"));
d1.addProject(p1);
d1.addProject(p2);
entityManager.persist(d1);
entityManager.persist(p1);
entityManager.persist(p2);
entityManager.flush();
entityManager.clear();
final List<Department> found = entityManager.createQuery(
"select d from Department d where id = :deptId", Department.class)
.setParameter("deptId", d1.getId())
.getResultList();
assertThat(found, is(not(nullValue())));
assertThat(found.size(), is(1));
assertThat(found.get(0).getProjects(), is(not(nullValue())));
assertThat(found.get(0).getProjects().size(), is(2));
for (final Project p : found.get(0).getProjects()) {
assertThat(p.getId().getDept().getCountry(), is(d1.getId().getCountry()));
assertThat(p.getId().getDept().getNumber(), is(d1.getId().getNumber()));
}
And it fails on this line:
assertThat(p.getId().getDept().getNumber(), is(d1.getId().getNumber()));
java.lang.AssertionError:
Expected: is <44>
got: <1>
<Click to see difference>
at org.junit.Assert.assertThat(Assert.java:750)
at org.junit.Assert.assertThat(Assert.java:709)
at jpa2.DeptProjTest.test1(DeptProjTest.java:75)
So all ProjectId#dept identifiers for the loaded collection items have been initialized to
{1, 1} pair, that is the DeptId#number value have been initialized with the DeptId#country
value, which is obviously wrong.
I've attached a Maven project with the entity classes, a JUnit test and a debug log,
so you should be able to easily reproduce it, should it be a new bug rather than a known
issue.
Thanks,
Anton
--
This message is automatically generated by JIRA.
For more information on JIRA, see:
http://www.atlassian.com/software/jira