JPA继承中的ManyToOne映射

3

我有几个实体,它们具有相同的属性,因此提取了像下面的公共参数。

@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;

    }

使用Hibernate进行OneToMany映射会在启动时导致异常,如下所示。

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

这不是 @MappedSuperclass 应该使用的方式吗?


你试过尝试抽象化它吗? - Mohamed Nabli
刚刚尝试了一下,没有成功。 - Somasundaram Sekar
@OneToMany(fetch = FetchType.LAZY, mappedBy = "group") private List<IndividualCustomer> customerDemographicDetails; - Mohamed Nabli
我有两种类型,个人和商业,因此仅在个人上进行静态类型设置将无法工作,这是我提取基本类型的主要原因。 - Somasundaram Sekar
1个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
3
您不能将关系映射到@MappedSuperclass。请参考参考文档 here@MappedSuperclass 仅允许您在域模型中实现继承。从数据库的角度来看,这使它成为一个实现细节。 @MappedSuperclass 可以轻松地将常见字段和注释分组到通常是抽象超类中,但您无法对其进行关联。 如果您使用 @Inheritance ,则可以摆脱此映射(请注意,我不得不将 GROUP 更改为其他内容,因为它是大多数数据库中的保留字):

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

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(无更改)

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;

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,