Как уже упоминалось в моем комментарии, вы могли бы сначала использовать @AttributeOverride
здесь
@Embeddable
public class BorrowId implements Serializable {
private PersonId person;
@AttributeOverride(
name = "library_code",
column = @Column(insertable=false, updatable=false) )
private BookId book;
// getter/setter(s) with proper equals/hashcode
}
Другой вариант, который вы могли бы рассмотреть, - вывести страницу из доменного дизайна:
@Embeddable
public class BorrowId implements Serializable {
private String person;
private String book;
private String libraryCode;
// Required by JPA
// notice its package private
BorrowId() {}
public BorrowId(PersonId person, BookId book) {
// validates you are pairing a person and book with same library codes
assert person.getLibraryCode().equals( book.getLibraryCode() );
this.person = person.getName();
this.book = book.getTitle();
this.libraryCode = person.getLibraryCode();
}
// expose all getters as public
// expose all setters as non-public
// implement proper equals/hashcode
}
Идея последнего решения здесь состоит в том, что мы используем управляемую доменом конструкцию, чтобы заставить единственный способ создать BorrowId
- предоставить ему идентификаторы Person
и Book
, что логично, как *Объекты 1011 *, Book
и Library
должны существовать раньше.
Если вы действительно хотите продвинуться на один шаг дальше, конструктор может быть
public BorrowId(Person person, Book book, Library library) {
assert library.getCode().equals( person.getId().getLibraryCode() );
assert library.getCode().equals( book.getId().getLibraryCode() );
this.person = person.getId().getName();
this.book = book.getId().getTitle();
this.library = library.getCode();
}
Hibernate позаботится о манипулировании кодом для правильного доступа к тому, что ему нужно из закрытых областей, так какнеобходимо, оставляя ограниченные области видимости, диктовать, как вы предполагаете использовать объект.