Hibernate:OneToMany关系WITHOUTH循环依赖

时间:2016-06-28 11:11:26

标签: java spring entity-framework hibernate

我有一个包含两个实体的OneToMany数据模型。一台机器包含许多特征。

问题:我正在尝试创建没有循环依赖的实体。

但是我得到了这个问题:

  Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in ServletContext resource [/WEB-INF/spring-config.xml]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574)
    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:956)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:747)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4842)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5303)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1407)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1397)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:1225)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.access$600(EntityManagerFactoryBuilderImpl.java:119)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:853)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:843)
    at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:398)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:842)
    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:318)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1633)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1570)
    ... 21 more
Caused by: org.hibernate.MappingException: Could not determine type for: java.util.Set, at table: machine, for columns: [org.hibernate.mapping.Column(characteristics)]
    at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:336)
    at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:310)
    at org.hibernate.mapping.Property.isValid(Property.java:241)
    at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:496)
    at org.hibernate.mapping.RootClass.validate(RootClass.java:270)
    at org.hibernate.cfg.Configuration.validate(Configuration.java:1358)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1849)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:850)
    ... 29 more

我的数据库:

机器:

enter image description here

创建声明:

CREATE TABLE `machine` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(45) NOT NULL,
  `description` varchar(45) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=utf8

实体:

@Entity
@Table(name = "machine")
public class Machine {
    private int machine_id; 

    private String name;

    private String description; 

    private Set<Characteristic> characteristics;

    public Set<Characteristic> getCharacteristics() {
        return characteristics; 
    }

    public void setCharacteristics(Set<Characteristic> characteristics){
        this.characteristics = characteristics;
    }

    public Machine(){}

    public Machine(String name, String description){
        this.name = name;
        this.description = description; 
    }

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="id")
    public int getId() {
        return machine_id;
    }

    public void setId(int machine_id) {
        this.machine_id = machine_id;
    }

    @Column(name="name")
    public String getName() {
        return name;
    }

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

    @Column(name="description")
    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

特性

enter image description here

创建声明:

CREATE TABLE `characteristic` (
  `characteristic_id` int(11) NOT NULL AUTO_INCREMENT,
  `machine_id` int(11) NOT NULL DEFAULT '0',
  `name` varchar(45) DEFAULT NULL,
  `description` varchar(45) DEFAULT NULL,
  `type` int(11) NOT NULL,
  `value` int(11) DEFAULT NULL,
  PRIMARY KEY (`characteristic_id`),
) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=latin1

实体:

@Entity
@Table(name = "characteristic")
public class Characteristic {
    private int characteristic_id; 

    private String name; 

    private String description; 

    private int type; 

    private int value;

    public Characteristic() {}

    public Characteristic(String description, int type, int value) {
        this.description = description;
        this.type = type;
        this.value = value;
    } 

    public Characteristic(int characteristic_id, String description, int type, int value) {
        this.characteristic_id = characteristic_id;
        this.description = description;
        this.type = type;
        this.value = value;
    } 

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="characteristic_id")
    public int getCharacteristic_Id() {
        return characteristic_id;
    }

    public void setCharacteristic_Id(int characteristic_id) {
        this.characteristic_id = characteristic_id;
    }

    @Column(name="name")
    public String getName() {
        return name;
    }

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

    @Column(name="description")
    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    @Column(name="type")
    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    @Column(name="value")
    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }
}

弹簧-config.xml中

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/data/jpa
    http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
    http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<context:component-scan base-package="com.mego.smscloud" />

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/maschinedb?serverTimezone=UTC"/>
        <property name="username" value="root"/>
        <property name="password" value=""/>
    </bean>

    <bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
        <property name="showSql" value="true"/>
        <property name="generateDdl" value="true"/>
        <property name="database" value="MYSQL"/>
    </bean>

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
        <property name="packagesToScan" value="com.mego.smscloud.entity"/>
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"/>

    <jpa:repositories base-package="com.mego.smscloud.repository" />

</beans>

1 个答案:

答案 0 :(得分:0)

它只是特征和机器之间映射的问题。 日志告诉Hibernate不知道用于映射的类型。 您应该在类Machine中的方法getCharacteristics()上添加@OneToMany批注。

你可以在这里查看OneToMany Unidirectional部分的集合映射(有或没有jointable): https://docs.jboss.org/hibernate/annotations/3.4/reference/en/html_single/#entity-mapping-association-collections

@Entity
@Table(name = "machine")
public class Machine {
    private int machine_id; 

    private String name;

    private String description; 

    private Set<Characteristic> characteristics;

    @OneToMany
    @JoinColumn(name="machine_id")
    public Set<Characteristic> getCharacteristics() {
        return characteristics; 
    }

    public void setCharacteristics(Set<Characteristic> characteristics){
        this.characteristics = characteristics;
    }

    public Machine(){}

    public Machine(String name, String description){
        this.name = name;
        this.description = description; 
    }

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="id")
    public int getId() {
        return machine_id;
    }

    public void setId(int machine_id) {
        this.machine_id = machine_id;
    }

    @Column(name="name")
    public String getName() {
        return name;
    }

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

    @Column(name="description")
    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

希望这个帮助