1

だからここに私の問題の簡単な説明があります。私は 2 つのテーブルを持っています。最初に個人の詳細が含まれています。

@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;
    }
}

2 番目のテーブルには、複数の個人設定が含まれています。

@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());

以前は JPA プロバイダーとして Hibernate を使用していましたが、そのコードは完全に機能します。残念ながら、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 では失敗します。

4

0 に答える 0