Hibernate继承问题 [英] Trouble with hibernate inheritance

查看:77
本文介绍了Hibernate继承问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请帮我解决这个问题 - 我有抽象类
和两个子元素:

  @Table(name =abstract_partner)
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class AbstractPartner {

@Id
protected Long id;
保护字符串名称;
保护字符串端点;
保护字符串代码;
@Column(name =api_key)
保护字符串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;
}

}

CustomerPartnerGroupEntity

  @Entity 
@Table(name =customer_partner_group)

public class CustomerPartnerGroupEntity扩展AbstractPartner {

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


$ / code $ / pre

NetworkPartner

  @Entity 
@Table(name =network_partners)

public class NetworkPartner extends AbstractPartner {

@OneToOne(mappedBy =partner,fetch = FetchType.EAGER,cascade = CascadeType.ALL)
@JsonIgnore
专用NetworkPartnerConfiguration配置;

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


@Override
public boolean equals(Object o){
if(this == o)return true;
if(!(o instanceof NetworkPartner))返回false;
NetworkPartner that =(NetworkPartner)o;
返回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;


$ / code>

并尝试通过Hibernate实现继承策略 - JOINED
但是当我使用这个策略时,我收到了异常:

 原因:org.springframework.beans.factory.BeanCreationException :在类路径资源[common-beans.xml]中定义名称为'entityManagerFactory'的bean时出错:init方法的调用失败;嵌套的异常是java.util.NoSuchElementException 
在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1572)
在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.AbstractAppl icationContext.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)美元,org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:109 b $ b)
在org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext( AbstractDelegatingSmartContextLoader.java:261)
at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDel
at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:86)
... 24 more
导致: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)
在org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:905)
在org.hibernate.ejb.Ejb3C onfiguration.buildEntityManagerFactory(Ejb3Configuration.java:890)
at org.springframework.orm.jpa.vendor.SpringHibernateEjbPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateEjbPersistenceProvider.java:51)
位于org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean。 createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:343)
在org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:318)
在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods( AbstractAutowireCapableBeanFactory.java:1631)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1568)
... 39 more

奇怪的事情 - 如果我选择另一个策略(SINGLE TABLE或TABLE_PER_CLASS)错误不会出现

解决方案

仅通过将策略从JOINED更改为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)
私人字符串名称;

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 class

  import javax.persistence.Column; 
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
$ b $ @Entity
@DiscriminatorValue(value =Contract_Employee)
public class Contract_Employee extends Employee {
@Column(name =pay_per_hour)
私人浮动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;


$ b code
$ b Regular_Employee Class strong>:

  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)
私人流动薪资;

@Column(name =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;




$ b主类函数
$ b $> / strong>:

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

Transaction tx = session.beginTransaction();

员工e1 =新员工();
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年5个月);
c1.setPay_per_hour(45.5f);

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

tx.commit();
session.close();
System.out.println(success ..);
}


please help me with such issue - i have abstract class and two child:

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

}

CustomerPartnerGroupEntity

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

NetworkPartner

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

and try to realise inheritance via Hibernate with strategy - JOINED but when i use this strategy i receive exception:

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

strange thing - if i choose another strategy(SINGLE TABLE or TABLE_PER_CLASS) error don't appear

解决方案

Just by changing the strategy from JOINED to SINGLE_TABLE will not resolve this issue. You need to add @DiscriminatorColumn in parent class and each class parent/child should have @DiscriminatorValue to distinguish the records in single table.

Below is an example code:
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 class:

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

}

Regular_Employee Class:

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

}

Main class function:

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..");
}

这篇关于Hibernate继承问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆