带有继承的JPA ManyToOne映射 [英] JPA ManyToOne mapping with Inheritance
问题描述
有几个具有共同属性的实体,因此提取了以下代码段等共同的参数.
Have a couple of entities, that have common attributes, hence extracted the common params like the below snippet.
@MappedSuperclass()
public class BaseCustomerDemographicDetails {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
protected long id;
@ManyToOne
@JoinColumn(name = "GROUP")
protected Group group;
}
实体片段如下.
@Entity
@Table(name = "INDIVIDUAL_CUSTOMER")
@Access(AccessType.FIELD)
public class IndividualCustomer extends BaseCustomerDemographicDetails {
@NotNull
@Embedded
private PersonalInformation personalInformation;
@Column(precision = 16, scale = 2)
private BigDecimal annualIncome;
private Boolean vip;
private Boolean isStaff;
...
}
@Entity
@Access(AccessType.FIELD)
@Table(name = "GROUP")
public class Group {
protected Group(){}
@Id
@NotNull
@Column(name = "GROUPID")
private String groupId;
@NotNull
@Column(name="GROUPNAME")
private String groupName;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "group")
private List<BaseCustomerDemographicDetails> customerDemographicDetails;
}
在statrtup期间,相同的OneToMany映射会导致Hibernate异常,如下所示.
The OneToMany mapping of the same results in Hibernate exception during statrtup as below.
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:1249)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.access$600(EntityManagerFactoryBuilderImpl.java:120)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:860)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:850)
at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:425)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:849)
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:343)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:319)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574)
... 16 common frames omitted
Caused by: org.hibernate.AnnotationException: Use of @OneToMany or @ManyToMany targeting an unmapped class: xx.xxx.xxxxxxx.xxxxxxxxx.domain.model.Group.customerDemographicDetails[xx.xxx.xxxxx.xxxxxxx.domain.model.BaseCustomerDemographicDetails]
at org.hibernate.cfg.annotations.CollectionBinder.bindManyToManySecondPass(CollectionBinder.java:1135)
at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:794)
at org.hibernate.cfg.annotations.CollectionBinder$1.secondPass(CollectionBinder.java:729)
at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:70)
at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1697)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1426)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1846)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:857)
... 24 common frames omitted
官方文档与我尝试执行的操作是同步的,但还算运气,请帮忙!!!
The official documentation is in sync with what I tried doing, yet of no luck, please help!!!!
http://docs.oracle.com/javaee/5/api/javax/persistence/MappedSuperclass.html 堆栈:带有Spring Data JPA的Spring Boot
http://docs.oracle.com/javaee/5/api/javax/persistence/MappedSuperclass.html Stack: Spring Boot with Spring Data JPA
推荐答案
您无法将关系映射到@MappedSuperclass.请在此处查看参考文档. . @MappedSuperclass
允许您仅在域模型中实现继承.从数据库的角度来看,这使它成为实现细节. @MappedSuperclass
使在通常为抽象的超类中对公共字段和注释的分组变得容易,但是您无法与其建立联系.
You can't map a relation to a @MappedSuperclass. Please look at the reference documentation here. @MappedSuperclass
allows you to implement inheritance only in the domain model. That makes it an implementation detail, from the database point of view. @MappedSuperclass
makes it easy to group common fields and annotations in a usually abstract superclass, but you can't make relations to it.
如果使用@Inheritance
,则可以摆脱这种映射关系(注意,我不得不将GROUP更改为其他名称,因为在大多数数据库中,GROUP是保留字):
If you use @Inheritance
, you can get away with this mapping (notice I had to change GROUP to something else as it is a reserved word in most databases):
BaseCustomerDemographicDetails.java
BaseCustomerDemographicDetails.java
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
@Entity(name = "BaseCustomerDemographicDetails")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class BaseCustomerDemographicDetails {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
protected long id;
@ManyToOne
@JoinColumn(name = "GROUP_OF_CUSTOMERS")
protected Group groupOfCustomers;
}
Group.java
Group.java
import java.util.List;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
@Entity
@Access(AccessType.FIELD)
@Table(name = "GROUP_OF_CUSTOMERS")
public class Group {
protected Group() {
}
@Id
@NotNull
@Column(name = "GROUPID")
private String groupId;
@NotNull
@Column(name = "GROUPNAME")
private String groupName;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "groupOfCustomers")
private List<BaseCustomerDemographicDetails> customerDemographicDetails;
}
IndividualCustomer.java(不变)
IndividualCustomer.java (no change)
import java.math.BigDecimal;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.Entity;
@Entity
@Access(AccessType.FIELD)
public class IndividualCustomer extends BaseCustomerDemographicDetails {
@NotNull
@Embedded
private PersonalInformation personalInformation;
@Column(precision = 16, scale = 2)
private BigDecimal annualIncome;
private Boolean vip;
private Boolean isStaff;
}
这篇关于带有继承的JPA ManyToOne映射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!