當我嘗試使用註釋設置我的模式時,我遇到了一些Hibernate的令人沮喪的行爲。假設我有一個與其他幾種類型具有一對多關係的實體。例如:JPA/Hibernate註釋不理解繼承?
@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;
}
}
一切似乎都很好,只是當我嘗試運行,然後休眠與爆炸:
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)
令人沮喪的是,如果我複製了ClubLocation
類中的club
屬性的getter和setter聲明,一切都很好。具體來說,它的工作原理髮現,如果我補充一下:
@Override
@ManyToOne(optional = false)
public Club getClub() {
return super.getClub();
}
public void setClub(Club club) {
super.setClub(club);
}
...到ClubLocation
類。但這沒有意義,因爲它所做的只是委託給超類。
Hibernate只是不夠複雜,無法處理繼承的映射字段,而沒有在子類中重新聲明getter/setter?如果Hibernate可以更優雅地處理這種情況,那麼需要如何設置/我做錯了什麼?