【问题标题】:Trouble with hibernate inheritance休眠继承问题
【发布时间】:2016-10-03 12:19:48
【问题描述】:

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

@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

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

【问题讨论】:

    标签: hibernate inheritance


    【解决方案1】:

    当我尝试运行时出现错误

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = { "classpath:common-beans.xml" })
    @TransactionConfiguration(defaultRollback = true)
    @Transactional
    public class PartnerDAOTest {
    
    private Partner partner;
    private SystemUser user;
    
    @Autowired
    private PartnerDAO partnerDAO;
    @Autowired
    private SystemUserService systemUserService;
    //
    @Autowired
    private SystemUserRoleService systemUserRoleService;
    
    static {
        System.setProperty("envTarget", "local");
    }
    
    
    public PartnerDAOTest() {
    }
    
    @Before
    public void testSave() {
        user = new SystemUser();
        user.setEmail("1@gmail.com");
        user.setPassword("11");
        //
        user.setRole(systemUserRoleService.findByName(SystemUserRole.Name.ROLE_ADMIN));
    
        this.systemUserService.persist(user);
    
        Assert.assertTrue(user.getId() > 0);
    
        partner = new Partner();
        partner.setEnabled(0);
        partner.setPkey(UUID.randomUUID().toString());
        partner.setApiKey(UUID.randomUUID().toString().substring(0, 32));
    
        Set<SystemUser> users = new HashSet<>();
        users.add(user);
        //partner.setSystemUsers(users);
        Set<Partner> partners = new HashSet<>();
        partners.add(partner);
        //user.setPartners(partners);
    
        this.partnerDAO.persist(partner);
    
        Assert.assertNotNull(partner);
        Assert.assertTrue(partner.getId() > 0);
    }
    
    @Test
    public void testGetById() {
        Partner found = this.partnerDAO.get(partner.getId());
    
        Assert.assertNotNull(found);
        Assert.assertTrue(partner.getId() == found.getId());
    }
    
    @Test
    public void testUpdate() {
        partner.setEnabled(1);
        this.partnerDAO.update(partner);
    
        Assert.assertEquals(partner.getEnabled(), 1);
    }
    
    @Test
    public void testFindByIds() {
        List<Long> ids = new ArrayList<>();
        ids.add(partner.getId());
    
        Set<Partner> partners = this.partnerDAO.findByIds(ids);
        Assert.assertTrue(CollectionUtils.isNotEmpty(partners));
    }
    

    }

    【讨论】:

      【解决方案2】:

      仅将策略从 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")
      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;
      }
      
      }
      

      Regular_Employee 类

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

      【讨论】:

      • 据我了解数据库结构中的问题,好像我将策略 @Inheritance(strategy= InheritanceType.JOINED) 更改为 TABLE_PER_CLASS 的 SINGLE_TABLE 然后不会出现错误
      • 我尝试做时出现错误
      • 您的意思是当您将策略从 JOINED 更改为 SINGLE_TABLE 时发生错误?
      猜你喜欢
      • 2013-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-03
      • 2011-03-30
      • 1970-01-01
      • 2021-03-16
      相关资源
      最近更新 更多