所以这里是我的问题的简短描述。我有两个表,第一个包含人员详细信息:
@Entity
@Converter(name = "uuidConverter", converterClass = UUIDConverter.class)
public class Person {
private UUID mId;
private String mLogin;
@Id
@UuidGenerator(name = "uuid")
@GeneratedValue(generator = "uuid")
@Column(name = "id", nullable = false)
@Convert("uuidConverter")
public UUID getId() {
return mId;
}
@Column(name = "login", nullable = false)
public String getLogin() {
return mLogin;
}
public Person setId(UUID id) {
mId = id;
return this;
}
public Person setLogin(String login) {
mLogin = login;
return this;
}
}
第二个表包含多人偏好:
@IdClass(PersonPreference.Pk.class)
@Table(name = "person_preference")
@Entity
@Converter(name = "uuidConverter", converterClass = UUIDConverter.class)
public class PersonPreference {
private Person mPerson;
private String mComponentUid;
private String mComponentProperties;
@SuppressWarnings("UnusedDeclaration")
static class Pk implements Serializable {
private String mComponentUid;
private UUID mPerson;
public String getComponentUid() {
return mComponentUid;
}
public void setComponentUid(String componentUid) {
mComponentUid = componentUid;
}
@Convert("uuidConverter")
public UUID getPerson() {
return mPerson;
}
public void setPerson(UUID person) {
mPerson = person;
}
@Override
public int hashCode() {
return Objects.hashCode(mComponentUid, mPerson);
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Pk other = (Pk) obj;
return Objects.equal(this.mComponentUid, other.mComponentUid) && Objects.equal(this.mPerson, other.mPerson);
}
}
@Id
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "person_id", nullable = false)
public Person getPerson() {
return mPerson;
}
@Id
@Column(name = "component_uid", nullable = false)
public String getComponentUid() {
return mComponentUid;
}
@Column(name = "component_properties", nullable = false)
public String getComponentProperties() {
return mComponentProperties;
}
public PersonPreference setPerson(Person person) {
mPerson = person;
return this;
}
public PersonPreference setComponentUid(String componentUid) {
mComponentUid = componentUid;
return this;
}
public PersonPreference setComponentProperties(String componentProperties) {
mComponentProperties = componentProperties;
return this;
}
@Override
public int hashCode() {
return Objects.hashCode(mPerson, mComponentUid, mComponentProperties);
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final PersonPreference other = (PersonPreference) obj;
return Objects.equal(this.mPerson, other.mPerson)
&& Objects.equal(this.mComponentUid, other.mComponentUid)
&& Objects.equal(this.mComponentProperties, other.mComponentProperties);
}
}
我还写了一个简单的测试:
Person person = new Person()
.setLogin("PersonPreferencePersistenceTestLogin");
PersonPreference personPreference = new PersonPreference()
.setPerson(person)
.setComponentUid("4028808C3AA49ABB013AA49ABB2B0000")
.setComponentProperties("{123}");
mPersonPreferenceService.save(personPreference);
Optional<PersonPreference> newPersonPreference = mPersonPreferenceService.getByPersonAndComponentUid(
person,
"4028808C3AA49ABB013AA49ABB2B0000"
);
Assert.assertEquals(personPreference.getComponentProperties(), newPersonPreference.get().getComponentProperties());
我们以前使用 Hibernate 作为 JPA 提供程序,并且该代码运行良好。不幸的是,在将 JPA 提供程序切换到 Eclipselink 之后,级联持久化无法正常工作。从日志中我发现:
--INSERT INTO PERSON (id, login) VALUES (?, ?)
bind => [f2ce518c-8f37-4fac-bf5b-c8225d228b28, PersonPreferencePersistenceTestLogin]
--INSERT INTO person_preference (component_uid, component_properties, person_id) VALUES (?, ?, ?)
bind => [4028808C3AA49ABB013AA49ABB2B0000, {123}, f2ce518c-8f37-4fac-bf5b-c8225d228b28]
--SELECT component_uid, component_properties, person_id FROM person_preference WHERE ((person_id = ?) AND (component_uid = ?))
bind => [null, 4028808C3AA49ABB013AA49ABB2B0000]
但是 person.getId() 返回空值。我不知道为什么?其他映射适用于级联持久化,但在 Eclipselink 中失败。