John Doe
John Doe

Reputation: 319

Hibernate AnnotationException - Spring 5 ang Hibernate 5 mapping entities

I have problem after deploy my app on Tomcat. I'm using Spring 5 and Hibernate 5. I exported DB models by Hibernate Tools. My error looks like mapping problem between Hibernate models.

In my entity class i import javax.persistence from library:

[Maven: org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.0.Final] javax.persistence public @interface Entity

Wydzialy Model

package com.example.model;
// Generated 2018-01-05 12:50:58 by Hibernate Tools 5.2.3.Final

import javax.persistence.*;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

/**
 * Wydzialy generated by hbm2java
 */
@Entity
@Table(name = "WYDZIALY")
@NamedQuery(name="Wydzialy.findAll", query="SELECT w FROM Wydzialy w")
public class Wydzialy {

    private long id;
    private String kod;
    private String nazwa;
    private Date dataUtworzenia;
    private Date dataModyfikacji;
    private long idUzytUtw;
    private long idUzytMod;
    private String czyAktywny;
    private String teryt;
    private Set<Sprawy> sprawies = new HashSet<Sprawy>(0);
    private Set<Referaty> referaties = new HashSet<Referaty>(0);

    public Wydzialy() {
    }

    public Wydzialy(long id, String kod, String nazwa, Date dataUtworzenia, Date dataModyfikacji, long idUzytUtw,
            long idUzytMod, String czyAktywny, String teryt) {
        this.id = id;
        this.kod = kod;
        this.nazwa = nazwa;
        this.dataUtworzenia = dataUtworzenia;
        this.dataModyfikacji = dataModyfikacji;
        this.idUzytUtw = idUzytUtw;
        this.idUzytMod = idUzytMod;
        this.czyAktywny = czyAktywny;
        this.teryt = teryt;
    }

    public Wydzialy(long id, String kod, String nazwa, Date dataUtworzenia, Date dataModyfikacji, long idUzytUtw,
            long idUzytMod, String czyAktywny, String teryt, Set<Sprawy> sprawies, Set<Referaty> referaties) {
        this.id = id;
        this.kod = kod;
        this.nazwa = nazwa;
        this.dataUtworzenia = dataUtworzenia;
        this.dataModyfikacji = dataModyfikacji;
        this.idUzytUtw = idUzytUtw;
        this.idUzytMod = idUzytMod;
        this.czyAktywny = czyAktywny;
        this.teryt = teryt;
        this.sprawies = sprawies;
        this.referaties = referaties;
    }

    @Id
    @Column(name = "ID", unique = true, nullable = false, precision = 10, scale = 0)
    @SequenceGenerator(name = "Wydzialy_ID_GENERATOR", sequenceName = "WYDZ_SEQ")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "Wydzialy_ID_GENERATOR")
    public long getId() {
        return this.id;
    }

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

    @Column(name = "KOD", nullable = false, length = 5)
    public String getKod() {
        return this.kod;
    }

    public void setKod(String kod) {
        this.kod = kod;
    }

    @Column(name = "NAZWA", nullable = false)
    public String getNazwa() {
        return this.nazwa;
    }

    public void setNazwa(String nazwa) {
        this.nazwa = nazwa;
    }

    @Temporal(TemporalType.DATE)
    @Column(name = "DATA_UTWORZENIA", nullable = false, length = 7)
    public Date getDataUtworzenia() {
        return this.dataUtworzenia;
    }

    public void setDataUtworzenia(Date dataUtworzenia) {
        this.dataUtworzenia = dataUtworzenia;
    }

    @Temporal(TemporalType.DATE)
    @Column(name = "DATA_MODYFIKACJI", nullable = false, length = 7)
    public Date getDataModyfikacji() {
        return this.dataModyfikacji;
    }

    public void setDataModyfikacji(Date dataModyfikacji) {
        this.dataModyfikacji = dataModyfikacji;
    }

    @Column(name = "ID_UZYT_UTW", nullable = false, precision = 10, scale = 0)
    public long getIdUzytUtw() {
        return this.idUzytUtw;
    }

    public void setIdUzytUtw(long idUzytUtw) {
        this.idUzytUtw = idUzytUtw;
    }

    @Column(name = "ID_UZYT_MOD", nullable = false, precision = 10, scale = 0)
    public long getIdUzytMod() {
        return this.idUzytMod;
    }

    public void setIdUzytMod(long idUzytMod) {
        this.idUzytMod = idUzytMod;
    }

    @Column(name = "CZY_AKTYWNY", nullable = false, length = 1)
    public String getCzyAktywny() {
        return this.czyAktywny;
    }

    public void setCzyAktywny(String czyAktywny) {
        this.czyAktywny = czyAktywny;
    }

    @Column(name = "TERYT", nullable = false, length = 8)
    public String getTeryt() {
        return this.teryt;
    }

    public void setTeryt(String teryt) {
        this.teryt = teryt;
    }

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "wydzialy")
    public Set<Sprawy> getSprawies() {
        return this.sprawies;
    }

    public void setSprawies(Set<Sprawy> sprawies) {
        this.sprawies = sprawies;
    }

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "wydzialy")
    public Set<Referaty> getReferaties() {
        return this.referaties;
    }

    public void setReferaties(Set<Referaty> referaties) {
        this.referaties = referaties;
    }
}

Referaty Model

package com.example.model;
// Generated 2018-01-05 12:50:58 by Hibernate Tools 5.2.3.Final

import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.*;

/**
 * Referaty generated by hbm2java
 */
@Entity
@Table(name = "REFERATY")
@NamedQuery(name="Referaty.findAll", query="SELECT r FROM Referaty r")
public class Referaty {

    private long id;
    private Wydzialy wydzialy;
    private String kod;
    private String nazwa;
    private Date dataUtworzenia;
    private Date dataModyfikacji;
    private long idUzytUtw;
    private long idUzytMod;
    private String czyAktywny;
    private Set<Sprawy> sprawies = new HashSet<Sprawy>(0);

    public Referaty() {
    }

    public Referaty(long id, Wydzialy wydzialy, String kod, String nazwa, Date dataUtworzenia, Date dataModyfikacji,
            long idUzytUtw, long idUzytMod, String czyAktywny) {
        this.id = id;
        this.wydzialy = wydzialy;
        this.kod = kod;
        this.nazwa = nazwa;
        this.dataUtworzenia = dataUtworzenia;
        this.dataModyfikacji = dataModyfikacji;
        this.idUzytUtw = idUzytUtw;
        this.idUzytMod = idUzytMod;
        this.czyAktywny = czyAktywny;
    }

    public Referaty(long id, Wydzialy wydzialy, String kod, String nazwa, Date dataUtworzenia, Date dataModyfikacji,
            long idUzytUtw, long idUzytMod, String czyAktywny, Set<Sprawy> sprawies) {
        this.id = id;
        this.wydzialy = wydzialy;
        this.kod = kod;
        this.nazwa = nazwa;
        this.dataUtworzenia = dataUtworzenia;
        this.dataModyfikacji = dataModyfikacji;
        this.idUzytUtw = idUzytUtw;
        this.idUzytMod = idUzytMod;
        this.czyAktywny = czyAktywny;
        this.sprawies = sprawies;
    }

    @Id
    @Column(name = "ID", unique = true, nullable = false, precision = 10, scale = 0)
    @SequenceGenerator(name = "Referaty_ID_GENERATOR", sequenceName = "REFE_SEQ")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "Referaty_ID_GENERATOR")
    public long getId() {
        return this.id;
    }

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

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "ID_WYDZ")
    public Wydzialy getWydzialy() {
        return this.wydzialy;
    }

    public void setWydzialy(Wydzialy wydzialy) {
        this.wydzialy = wydzialy;
    }

    @Column(name = "KOD", length = 5)
    public String getKod() {
        return this.kod;
    }

    public void setKod(String kod) {
        this.kod = kod;
    }

    @Column(name = "NAZWA")
    public String getNazwa() {
        return this.nazwa;
    }

    public void setNazwa(String nazwa) {
        this.nazwa = nazwa;
    }

    @Temporal(TemporalType.DATE)
    @Column(name = "DATA_UTWORZENIA", length = 7)
    public Date getDataUtworzenia() {
        return this.dataUtworzenia;
    }

    public void setDataUtworzenia(Date dataUtworzenia) {
        this.dataUtworzenia = dataUtworzenia;
    }

    @Temporal(TemporalType.DATE)
    @Column(name = "DATA_MODYFIKACJI", length = 7)
    public Date getDataModyfikacji() {
        return this.dataModyfikacji;
    }

    public void setDataModyfikacji(Date dataModyfikacji) {
        this.dataModyfikacji = dataModyfikacji;
    }

    @Column(name = "ID_UZYT_UTW", precision = 10, scale = 0)
    public long getIdUzytUtw() {
        return this.idUzytUtw;
    }

    public void setIdUzytUtw(long idUzytUtw) {
        this.idUzytUtw = idUzytUtw;
    }

    @Column(name = "ID_UZYT_MOD", nullable = false, precision = 10, scale = 0)
    public long getIdUzytMod() {
        return this.idUzytMod;
    }

    public void setIdUzytMod(long idUzytMod) {
        this.idUzytMod = idUzytMod;
    }

    @Column(name = "CZY_AKTYWNY", nullable = false, length = 1)
    public String getCzyAktywny() {
        return this.czyAktywny;
    }

    public void setCzyAktywny(String czyAktywny) {
        this.czyAktywny = czyAktywny;
    }

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "referaty")
    public Set<Sprawy> getSprawies() {
        return this.sprawies;
    }

    public void setSprawies(Set<Sprawy> sprawies) {
        this.sprawies = sprawies;
    }
}

My Hibernate Config Class:

package com.example.config;

import com.example.model.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@EnableTransactionManagement
public class HibernateConfig {

    @Autowired
    private ApplicationContext context;

    @Bean
    public LocalSessionFactoryBean getSessionFactory() {
        LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean();
        Resource resource = context.getResource("classpath:hibernate.cfg.xml");
        System.out.println("resource.isFile(): " + resource.isFile());
        factoryBean.setConfigLocation(resource);
        factoryBean.setAnnotatedClasses(Pracownicy.class);
        factoryBean.setAnnotatedClasses(Referaty.class);
        factoryBean.setAnnotatedClasses(Rejestry.class);
        factoryBean.setAnnotatedClasses(SJrwa.class);
        factoryBean.setAnnotatedClasses(Sprawy.class);
        factoryBean.setAnnotatedClasses(SStatusySpraw.class);
        factoryBean.setAnnotatedClasses(Wydzialy.class);
        return factoryBean;
    }

    @Bean
    public HibernateTransactionManager getTransactionManager() {
        HibernateTransactionManager transactionManager = new HibernateTransactionManager();
        transactionManager.setSessionFactory(getSessionFactory().getObject());
        return transactionManager;
    }
}

My POM.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>testsoa</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <failOnMissingWebXml>false</failOnMissingWebXml>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.0.1</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.1</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.2.12.Final</version>
        </dependency>

        <dependency>
            <groupId>com.oracle</groupId>
            <artifactId>ojdbc6</artifactId>
            <version>11.2.0.3</version>
        </dependency>

        <dependency>
            <groupId>org.hsqldb</groupId>
            <artifactId>hsqldb</artifactId>
            <version>2.2.8</version>
        </dependency>

        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>5.4.1.Final</version>
        </dependency>
    </dependencies>


    <build>
        <finalName>testsoa</finalName>
        <sourceDirectory>src/main/java</sourceDirectory>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

When i build war and deploy on Apache Tomcat 8.5.24 i see this error:

19-Jan-2018 12:43:20.378 SEVERE [localhost-startStop-1] org.springframework.web.context.ContextLoader.initWebApplicationContext Context initialization failed
 org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'getSessionFactory' defined in com.example.config.HibernateConfig: Invocation of init method
 failed; nested exception is org.hibernate.AnnotationException: Use of @OneToMany or @ManyToMany targeting an unmapped class: com.example.model.Wydzialy.referaties[com.example.mode
l.Referaty]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1710)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:583)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:502)
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:312)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:742)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:868)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
        at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:409)
        at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:291)
        at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:103)
        at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4743)
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5207)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
        at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:752)
        at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:728)
        at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734)
        at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:986)
        at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1857)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)
Caused by: org.hibernate.AnnotationException: Use of @OneToMany or @ManyToMany targeting an unmapped class: com.example.model.Wydzialy.referaties[com.example.model.Referaty]
        at org.hibernate.cfg.annotations.CollectionBinder.bindManyToManySecondPass(CollectionBinder.java:1253)
        at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:810)
        at org.hibernate.cfg.annotations.CollectionBinder$1.secondPass(CollectionBinder.java:735)
        at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:54)
        at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1621)
        at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1589)
        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:691)
        at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:726)
        at org.springframework.orm.hibernate5.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:535)
        at org.springframework.orm.hibernate5.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:519)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1769)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1706)
        ... 25 more

Question: What is wrong in my Hibernate models code?

Upvotes: 0

Views: 1536

Answers (3)

garfield
garfield

Reputation: 595

if you check your log correctly you will see: Caused by: org.hibernate.AnnotationException: Use of @OneToMany or @ManyToMany targeting an unmapped class: com.example.model.Wydzialy.referaties[com.example.model.Referaty]

In your code

class Wydzialy

@OneToMany(fetch = FetchType.LAZY, mappedBy = "wydzialy")
public Set<Sprawy> getSprawies() {
    return this.sprawies;
}

class Referaty

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ID_WYDZ")
public Wydzialy getWydzialy() {
    return this.wydzialy;
}

You need to replace Set<Sprawy> with Set<Wydzialy> to have a valid bidirectional relationship.

Also in @ManyToOne(fetch = FetchType.LAZY)

FetchType.LAZY doesn't make sense since ManyToOne is a single value association.

Upvotes: 0

Wilder Valera
Wilder Valera

Reputation: 1019

Take a look to this configuration:

@Configuration
@EnableTransactionManagement
@PropertySource(value = { "classpath:myproject.properties" })
public class HibernateConfiguration {

@Autowired
private Environment env;

@Bean
public SessionFactory  sessionFactory() {
    LocalSessionFactoryBuilder builder = new LocalSessionFactoryBuilder(dataSource());
    builder.scanPackages("com.example.model").addProperties(hibernateProperties());
    return builder.buildSessionFactory();
}

@Bean
public DataSource dataSource() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName(env.getRequiredProperty("jdbc.driverClassName"));
    dataSource.setUrl(env.getRequiredProperty("jdbc.url"));
    dataSource.setUsername(env.getRequiredProperty("jdbc.username"));
    dataSource.setPassword(env.getRequiredProperty("jdbc.password"));
    return dataSource;
}

private Properties hibernateProperties() {
    Properties properties = new Properties();
    properties.put("hibernate.dialect", env.getRequiredProperty("hibernate.dialect"));
    properties.put("hibernate.show_sql", env.getRequiredProperty("hibernate.show_sql"));
    properties.put("hibernate.format_sql", env.getRequiredProperty("hibernate.format_sql"));
    properties.put("hibernate.jdbc.batch_size", env.getRequiredProperty("hibernate.jdbc.batch_size"));
    return properties;
}

@Bean
public HibernateTransactionManager txManager() {
    return new HibernateTransactionManager(sessionFactory());
}

}

Notice the builder.scanPackages("com.example.model"), this will give you a better way to scan Entities and you no longer need to add them manually.

In your config the error might be due Entities registration order. So, with the previous config let spring to the job.

PD: you can use @Value to set your property values from the properties file

Upvotes: 1

JB Nizet
JB Nizet

Reputation: 691635

setAnnotatedClasses() ... sets the annotated classes. So, every time you call it, you replace the previously set classes by the new ones. Call it once, and pass all the annotated classes as argument..

Upvotes: 3

Related Questions