0

2 つの hibernate/JPA エンティティがあります

@Entity
@Table(name = "conference_room", uniqueConstraints = @UniqueConstraint(columnNames = "code"))
class ConferenceRoom {
    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "id", unique = true, nullable = false)
    private Integer     id;
    @Column(name = "code", unique = true, length = 20)
    private String      code;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "conferenceRoom")
    @Cascade({CascadeType.ALL})
    private Set<Person> people       = new HashSet<Person>();
    // Appropriate getters and setters
}

@Entity
@Table(name = "person")
class Person {
    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "id", unique = true, nullable = false)
    private Integer     id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "conference_room_code", referencedColumnName = "code")
    private ConferenceRoom  conferenceRoom ;
    // Appropriate getters and setters
}

さらに、私のデータベース スキーマでは、conference_room.code 列を参照する person.conference_room_code に外部キー制約があります。

@Transactional私が次のことをすれば春の方法で

public ConferenceRoom getNewConferenceRoom(Person p) {
    ConferenceRoom r = new ConferenceRoom();
    r.setCode("MyUniqueGeneratedCode");
    r.getPeople().add(p);
    // sessionFactory is spring injected member
    sessionFactory.getCurrentSession().merge(r); 
}

すべてが正しく保存され、person の行が適切に更新され、新しい conference_room 行が追加されます。

しかし、その後、楽観的ロック db 更新のサポートを Date フィールドの Person クラスに追加しようとしたので、新しい Person クラス

@Entity
@Table(name = "person")
class Person {
    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "id", unique = true, nullable = false)
    private Integer         id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "conference_room_code", referencedColumnName = "code")
    private ConferenceRoom  conferenceRoom ;

    @Version
    @Column(name = "updated", length = 19)
    private Date            updated;
    // Appropriate getters and setters
}

MYSQL タイムスタンプ列のこの新しい「更新された」列は、挿入および更新時に current_timestamp のデフォルト値を持ちます。

上記のメソッドが実行されると、

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:
Cannot add or update a child row: a foreign key constraint fails (`schema`.`person`, CONSTRAINT `fk_room_code` FOREIGN KEY (`conference_room_code`) REFERENCES `conference_room` (`code`) ON DELETE NO ACTION ON UPDATE NO ACTION)
 ....

@Versionにフィールドを追加しようとしましたConferenceRoomが、うまくいきませんでした。

@Version を追加すると問題が発生する理由がわかりません。外部キー制約または新しく追加された @Version フィールドを削除すると、例外なくコードが再び機能し始めます。

外部キー制約を削除したくありません。この問題を回避する他の方法はありますか。

4

1 に答える 1