注釈を使用してスキーマを設定しようとすると、Hibernate でイライラするような動作が発生します。他のいくつかの型と 1 対多の関係を持つエンティティがあるとします。例えば:
@Entity
@Table(name = "clubs")
public class Club {
private long id;
private String name;
//...
private Collection<ClubLocation> locations;
public Club() {
this.name = null;
//...
this.locations = Collections.emptyList();
}
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Column(nullable = false)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@OneToMany(mappedBy = "club")
public Collection<ClubLocation> getLocations() {
return locations;
}
public void setLocations(Collection<ClubLocation> locations) {
this.locations = locations;
}
}
前述したように、このエンティティを他の多くのエンティティに関連付けたいので、関係を管理するスーパークラス エンティティを定義して、Club
関連付けられた各エンティティで関係を設定する必要がないようにすることをお勧めします。クラス。私はこれを使用して行います:
@Entity
@Table(name = "clubItems")
@Inheritance(strategy = InheritanceType.JOINED)
public class ClubItem {
protected Club club;
public ClubItem() {
this.club = null;
}
@ManyToOne(optional = false)
public Club getClub() {
return club;
}
public void setClub(Club club) {
this.club = club;
}
}
そして、そのクラスを次のように拡張します。
@Entity
@Table(name = "clubLocations")
public class ClubLocation extends ClubItem {
private String title;
//...
public ClubLocation() {
this.title = null;
//...
}
@Column(nullable = false)
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
実行しようとすると、Hibernate が次のように爆発する場合を除いて、すべて問題ないようです。
org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: ClubLocation.club in Club.locations
[WARNING] [talledLocalContainer] at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:543)
[WARNING] [talledLocalContainer] at org.hibernate.cfg.annotations.CollectionBinder$1.secondPass(CollectionBinder.java:508)
[WARNING] [talledLocalContainer] at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:43)
[WARNING] [talledLocalContainer] at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1127)
[WARNING] [talledLocalContainer] at org.hibernate.cfg.AnnotationConfiguration.secondPassCompile(AnnotationConfiguration.java:296)
[WARNING] [talledLocalContainer] at org.hibernate.cfg.Configuration.buildMappings(Configuration.java:1112)
[WARNING] [talledLocalContainer] at org.hibernate.ejb.Ejb3Configuration.buildMappings(Ejb3Configuration.java:1233)
[WARNING] [talledLocalContainer] at org.hibernate.ejb.EventListenerConfigurator.configure(EventListenerConfigurator.java:154)
[WARNING] [talledLocalContainer] at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:869)
[WARNING] [talledLocalContainer] at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:183)
[WARNING] [talledLocalContainer] at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:240)
[WARNING] [talledLocalContainer] at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:120)
[WARNING] [talledLocalContainer] at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:83)
[WARNING] [talledLocalContainer] at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:60)
イライラすることに、クラスclub
内のプロパティの getter および setter 宣言を複製すると、すべてがうまくいきます。ClubLocation
具体的には、次を追加すると機能します。
@Override
@ManyToOne(optional = false)
public Club getClub() {
return super.getClub();
}
public void setClub(Club club) {
super.setClub(club);
}
...ClubLocation
クラスに。しかし、スーパークラスに委譲するだけなので、それは無意味です。
Hibernate は、サブクラスで getter/setter を再宣言せずに継承されたマッピング フィールドを処理できるほど洗練されていないのでしょうか? Hibernate がこのケースをより適切に処理できる場合、どのようにセットアップする必要がありますか?/何が間違っているのでしょうか?