基于UUID标识的级联持久化复合主键映射的问题

时间:2012-11-05 21:59:42

标签: java jpa-2.0 eclipselink

所以这里是我的问题的简短描述。我有两个表,首先包含人员详细信息:

@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()返回null值。我不知道为什么?其他映射在级联持久化时工作正常,但在Eclipselink中失败。

0 个答案:

没有答案