Search code examples
javaxmlhibernatejakarta-eehibernate-mapping

Join columns error in Hibernate (One-to-many)


When using Hibernate I came across the following problem: The error keeps telling me that I have a wrong entity. Can someone take a closer look to this problem because I can not figure out what went wrong.

I have added RevalMeasurements.hbm.xml and RevalUser.hbm.xml to hibernate.

RevalMeasurement.hbm.xml

<hibernate-mapping>
        <class name="be.uhasselt.MediQ.model.RevalMeasurement" table="reval_measurements">
        <meta attribute="class-description">
            This class contains the reval measurement details.
        </meta>
            <id name="measurementId" type="java.lang.Long">
                <column name="measurement_id" />
                <generator class="identity" />
            </id>
            <property name="createdAt" type="timestamp">
                <column name="measurement_created" not-null="true"/>
            </property>     
            <many-to-one name="revalUser" column="user_id" class="be.uhasselt.MediQ.model.RevalUser" fetch="select">
            </many-to-one>
        </class>
    </hibernate-mapping>

RevalUser.hbm.xml

<hibernate-mapping>
    <class name="be.uhasselt.MediQ.model.RevalUser" table="reval_users">
    <meta attribute="class-description">
        This class contains the user details.
    </meta>
        <id name="userId" type="java.lang.Long">
            <column name="user_id" />
            <generator class="identity" />
        </id>
        <property name="userName" type="string">
            <column name="user_name" length="30" not-null="true"/>
        </property>
        <property name="userLastName" type="string">
            <column name="user_lastname" length="30" not-null="true"/>
        </property>
        <property name="userSpeed" type="double">
            <column name="user_speed" not-null="true" />
        </property>
        <set name="revalMeasurements" table="reval_measurements" inverse="true" lazy="true" fetch="select">
            <key>
                <column name="user_id" not-null="true" />
            </key>
            <one-to-many class="be.uhasselt.MediQ.model.RevalMeasurements" />
        </set>
    </class>
</hibernate-mapping>

Hibernate.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:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- Hibernate session factory -->
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">

        <property name="dataSource">
            <ref bean="dataSource" />
        </property>

        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>

        <property name="mappingResources">
            <list>
                <value>/hibernate/User.hbm.xml</value>
                <value>/hibernate/Measurement.hbm.xml</value>
                <value>/hibernate/PressureMeasurement.hbm.xml</value>
                <value>/hibernate/KlavUser.hbm.xml</value>
                <value>/hibernate/SneezeFeed.hbm.xml</value>
                <value>/hibernate/SneezeChannel.hbm.xml</value>
                <value>/hibernate/RevalUser.hbm.xml</value>
                <value>/hibernate/RevalMeasurement.hbm.xml</value>
            </list>
        </property>
    </bean>

    <tx:annotation-driven />
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

</beans>  

RevalMeasurement.java

import java.util.Date;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

import org.jsondoc.core.annotation.ApiObject;
import org.jsondoc.core.annotation.ApiObjectField;

@Entity
@ApiObject
public class RevalMeasurement {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @ApiObjectField(description = "The measurements ID")
    private Long measurementId;

    @ApiObjectField(description = "The time of the measurements")
    private Date createdAt;

    @ApiObjectField(description = "The measurements user")
    private RevalUser revalUser;

    public RevalMeasurement() {

    }

    public RevalMeasurement(Long measurementId, Date createdAt, RevalUser revalUser) {
        this.measurementId = measurementId;
        this.createdAt = createdAt;
        this.revalUser = revalUser;
    }

    public Long getMeasurementId() {
        return measurementId;
    }

    public void setMeasurementId(Long measurementId) {
        this.measurementId = measurementId;
    }

    public Date getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(Date createdAt) {
        this.createdAt = createdAt;
    }

    public RevalUser getRevalUser() {
        return revalUser;
    }

    public void setRevalUser(RevalUser revalUser) {
        this.revalUser = revalUser;
    }
}

RevalUser.java

import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

import org.jsondoc.core.annotation.ApiObject;
import org.jsondoc.core.annotation.ApiObjectField;

@Entity
@ApiObject
public class RevalUser {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @ApiObjectField(description = "The users ID")
    private Long userId;

    @ApiObjectField(description = "The users name")
    private String userName;

    @ApiObjectField(description = "The users last name")
    private String userLastName;

    @ApiObjectField(description = "The users speed")
    private Double userSpeed;

    @ApiObjectField(description = "The users measurements")
    private Set<RevalMeasurement> revalMeasurements;

    public Long getUserId() {
        return userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserLastName() {
        return userLastName;
    }

    public void setUserLastName(String userLastName) {
        this.userLastName = userLastName;
    }

    public Double getUserSpeed() {
        return userSpeed;
    }

    public void setUserSpeed(Double userSpeed) {
        this.userSpeed = userSpeed;
    }

    public Set<RevalMeasurement> getRevalMeasurements() {
        return revalMeasurements;
    }

    public void setRevalMeasurements(Set<RevalMeasurement> revalMeasurements) {
        this.revalMeasurements = revalMeasurements;
    }
}

Error

Caused by: org.hibernate.boot.MappingException: Association [be.uhasselt.MediQ.model.RevalUser.revalMeasurements] references an unmapped entity [be.uhasselt.MediQ.model.RevalUser.revalMeasurements] : origin(null)
    at org.hibernate.boot.model.source.internal.hbm.ModelBinder$AbstractPluralAttributeSecondPass.bindCollectionTable(ModelBinder.java:3137)
    at org.hibernate.boot.model.source.internal.hbm.ModelBinder$AbstractPluralAttributeSecondPass.doSecondPass(ModelBinder.java:3075)
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1655)
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1623)
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:278)
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.build(MetadataBuildingProcess.java:83)
    at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:418)
    at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:87)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:692)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:724)
    at org.springframework.orm.hibernate5.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:416)
    at org.springframework.orm.hibernate5.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:401)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574)
    ... 32 more

Solution

  • Found the problem: in my RevalUser.hbm.xml I typed <one-to-many class="be.uhasselt.MediQ.model.RevalMeasurements" /> instead of <one-to-many class="be.uhasselt.MediQ.model.RevalMeasurement" />