当前位置: 首页 > 知识库问答 >
问题:

hibernate继承的问题

商柏
2023-03-14
@Table(name = "abstract_partner")
@Inheritance(strategy= InheritanceType.JOINED)
public abstract class AbstractPartner {

@Id
protected Long id;
protected String name;
protected String endpoint;
protected String code;
@Column(name = "api_key")
protected String apiKey;

public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getEndpoint() {
    return endpoint;
}

public void setEndpoint(String endpoint) {
    this.endpoint = endpoint;
}

public String getCode() {
    return code;
}

public void setCode(String code) {
    this.code = code;
}

@Override
public abstract boolean equals(Object o);

@Override
public int hashCode() {
    return Objects.hash(id);
}

public String getApiKey() {
    return apiKey;
}

public void setApiKey(String apiKey) {
    this.apiKey = apiKey;
}
@Entity
@Table(name = "customer_partner_group")

public class CustomerPartnerGroupEntity extends AbstractPartner{

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof CustomerPartnerGroupEntity)) return false;
    CustomerPartnerGroupEntity that = (CustomerPartnerGroupEntity) o;
    return Objects.equals(id, that.id);
}
}
@Entity
@Table(name = "network_partners")

public class NetworkPartner extends AbstractPartner{

@OneToOne(mappedBy = "partner", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JsonIgnore
private NetworkPartnerConfiguration configuration;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "payment_provider_id")
@JsonIgnore
private PaymentProviderEntity paymentProvider;


@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof NetworkPartner)) return false;
    NetworkPartner that = (NetworkPartner) o;
    return Objects.equals(id, that.id);
}

public NetworkPartnerConfiguration getConfiguration() {
    return configuration;
}

public void setConfiguration(NetworkPartnerConfiguration configuration) {
    this.configuration = configuration;
}

public PaymentProviderEntity getPaymentProvider() {
    return paymentProvider;
}

public void setPaymentProvider(PaymentProviderEntity paymentProvider) {
    this.paymentProvider = paymentProvider;
}
}

并尝试通过Hibernate使用策略连接实现继承,但当我使用此策略时,我收到异常:

Caused by: org.springframework.beans.factory.BeanCreationException: Error     creating bean with name 'entityManagerFactory' defined in class path resource [common-beans.xml]: Invocation of init method failed; nested exception is java.util.NoSuchElementException
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1572)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:960)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:749)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:125)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:109)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:261)
at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:68)
at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:86)
... 24 more
Caused by: java.util.NoSuchElementException
at java.util.ArrayList$Itr.next(ArrayList.java:854)
at org.hibernate.cfg.annotations.TableBinder.linkJoinColumnWithValueOverridingNameIfImplicit(TableBinder.java:487)
at org.hibernate.cfg.PkDrivenByDefaultMapsIdSecondPass.doSecondPass(PkDrivenByDefaultMapsIdSecondPass.java:54)
at org.hibernate.cfg.Configuration.processSecondPassesOfType(Configuration.java:1386)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1337)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1730)
at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:94)
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:905)
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:890)
at org.springframework.orm.jpa.vendor.SpringHibernateEjbPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateEjbPersistenceProvider.java:51)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:343)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:318)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1631)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1568)
... 39 more

奇怪的是,如果我选择另一个策略(单表或TABLE_PER_CLASS),错误不会出现

共有1个答案

郭远
2023-03-14

仅仅通过将策略从JOEN改为SINGLE_TABLE并不能解决这个问题。您需要在父类中添加@DiscriminatorColumn,并且每个类父/子类都应该有@DiscriminatorValue来区分单个表中的记录。

下面是一个示例代码:
employee.java

import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.DiscriminatorValue;
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.Table;

@Entity
@Table(name = "employee_tph")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "object_type", discriminatorType = DiscriminatorType.STRING)
@DiscriminatorValue(value = "Employee")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "Employee_Id")
private long empId;

@Column(name = "Employee_Name")
private String name;

public long getEmpId() {
    return empId;
}

public void setEmpId(long empId) {
    this.empId = empId;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

}

Contract_Employee类:

import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;

@Entity
@DiscriminatorValue(value = "Contract_Employee")
public class Contract_Employee extends Employee {
@Column(name = "pay_per_hour")
private float pay_per_hour;

@Column(name = "contract_period")
private String contract_period;

public float getPay_per_hour() {
    return pay_per_hour;
}

public void setPay_per_hour(float pay_per_hour) {
    this.pay_per_hour = pay_per_hour;
}

public String getContract_period() {
    return contract_period;
}

public void setContract_period(String contract_period) {
    this.contract_period = contract_period;
}

}
import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;

@Entity
@DiscriminatorValue(value = "Regular_Employee")
public class Regular_Employee extends Employee {
@Column(name = "salary")
private float salary;

@Column(name = "bonus")
private float bonus;

public float getSalary() {
    return salary;
}

public void setSalary(float salary) {
    this.salary = salary;
}

public float getBonus() {
    return bonus;
}

public void setBonus(float bonus) {
    this.bonus = bonus;
}

}
public static void main(String[] args) {
    SessionFactory sessionFactory=HibernateUtil.getSessionAnnotationFactory();
    Session session=sessionFactory.openSession();

    Transaction tx=session.beginTransaction();

    Employee e1=new Employee();
    e1.setName("Rohit");

    Regular_Employee r1=new Regular_Employee();
    r1.setBonus(1000.50f);
    r1.setName("Peter");
    r1.setSalary(45000.56f);

    Contract_Employee c1=new Contract_Employee();
    c1.setName("Harry");
    c1.setContract_period("4 yrs 5 months");
    c1.setPay_per_hour(45.5f);

    session.persist(e1);
    session.persist(c1);
    session.persist(r1);

    tx.commit();
    session.close();
    System.out.println("success..");
}
 类似资料:
  • 假设类“X”映射到表“X”,类“A”映射到表“A”,类“B”映射到表“B”。 表X结构:(X_ID,一些其他列表A结构:(A_Id,X_Id,一些其他列)表B结构:(A_Id,一些其他列)...表B也有A_Id “B”类扩展了“A”类。我们将它们的映射文件都设置为: “A”类父映射文件: “B”类映射文件: 现在,我有一个SQL查询,如下所示,我需要使用hibernate criteria API

  • 我有两个实体BillingAddress和ShippingAddress映射到具有鉴别器类型列的表地址。 我能够使用不同的类型值在DB中成功保存/更新两个地址类型。 我面临的问题是当我查询地址表时,如下所示: 这工作正常,但查询ShippingAddress会引发非均匀查询结果异常,即结果中同时包含ShippingAddress和Billingaddress。请让我知道,我应该怎么做。

  • 我有4个实体: ,,, 和4个表: 现在我想在一个查询中选择所有有课程的用户(如果存在的话)(注意用户没有课程)这个select生成如下所示: 您可以清楚地看到,Hibernate没有与t_student_course表连接 我正在使用Hibernate 4.1 Final 问题:Hibernate支持这样的查询吗 a)如果支持,那么为什么它不为实体获取课程? b)如果不支持,我如何选择所有的用户

  • 1. 前言 本节课程和大家一起学习继承映射。通过本节课程的学习,你将了解到: 什么是继承映射; 实现继承映射的 3 种方案。 2. 继承映射 学习继承映射之前,需要搞清楚什么是继承映射? 继承是 OOP 中的概念,其目的除了复用代码之外,还用来描述对象在现实世界中的关系。 为了更好地讲解继承映射,咱们再在数据库中创建一张老师表。数据库中多了一张表,按照使用 Hibernate 的套路,理所当然应该

  • 我在Hibernate中有道传承,下面是代码: 用户DAO: 我有一个域类用户和两个子类用户:Customer和Sales。我有两个dao类,分别用于客户和销售。 用户DAO: 客户道: 销售DAO: 我的问题是,当我使用CusterDap调用方法getUserByUsername()(继承自BaseDaoImpl)与销售的用户名(拥有用户名的用户是SalesRep的实例,而不是客户)时,它会抛出

  • 从标准 JPA (EclipseLink) 迁移到Hibernate时,由于子记录数量不正确和/或子对象的类型无效,测试失败。我认为问题是Hibernate生成的 SQL 没有在InheritanceType.SINGLE_TABLE关系的 where 子句中使用鉴别器列。 关于在映射中更改什么的任何建议? 提前感谢, 蒂莫西 环境 < li>postgres 9.6.17 < li >Sprin