Well, as you might know I started learning/coding Java because I will kinda be working in production and as you might know in my first month in Java I got the idea to write a book about it. Here is how the cover would look.
Anyway this is not the point of this particular post. So let’s see what we got. We got a very unusual exception: org.hibernate.MappingException: Unknown entity.
We tried to use annotated hibernate entities, everything seemed to be nice configured in hibernate.xml but it didn’t worked. Our Hibernate should work with Spring. So I’ll put some XML’s and classes before and than I’ll tell you the solution
<?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"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<!-- Hibernate session factory -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.postgresql.Driver" />
<property name="url" value="jdbc:postgresql://localhost:5432/testh" />
<property name="username" value="postgres" />
<property name="password" value="postgres" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="entity" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- The Spring support for Hibernate calls -->
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>
The property “packagesToScan” is used to indicate where the hibernate annotation entities are.
Now the entity java class was like this
package entity;
import java.io.Serializable;
import java.sql.Timestamp;
import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.Entity;
@Entity
@Table(name = "emp", schema = "public")
public class Employee implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "emp_userid")
private String id;
@Column(name = "emp_link_date")
private Timestamp date;
@Column(name = "emp_logdel")
private boolean logicalDelete;
@Column(name = "emp_name")
private String name;
@Column(name = "employee_surname")
private String surname;
public Employee() {
// TODO Auto-generated constructor stub
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Timestamp getDate() {
return date;
}
public void setDate(Timestamp date) {
this.date = date;
}
public boolean getLogicalDelete() {
return logicalDelete;
}
public void setLogicalDelete(boolean logicalDelete) {
this.logicalDelete = logicalDelete;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public boolean isLogicalDelete() {
return logicalDelete;
}
}
Well I got this error which was kind of stupid:
org.hibernate.MappingException: Unknown entity: entity.Employee
at org.hibernate.impl.SessionFactoryImpl.getEntityPersister(SessionFactoryImpl.java:597)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:68)
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:879)
at org.hibernate.impl.SessionImpl.get(SessionImpl.java:816)
at org.hibernate.impl.SessionImpl.get(SessionImpl.java:809)
at com.givaudan.persistence.UserDaoBean.getUserById(UserDaoBean.java:12)
at com.givaudan.masterdata.service.UserRightsServiceBean.getUserById(UserRightsServiceBean.java:12)
at service.UserRightsServiceTest.testGetUserById(UserRightsServiceTest.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.test.context.junit4.SpringTestMethod.invoke(SpringTestMethod.java:160)
at org.springframework.test.context.junit4.SpringMethodRoadie.runTestMethod(SpringMethodRoadie.java:233)
at org.springframework.test.context.junit4.SpringMethodRoadie$RunBeforesThenTestThenAfters.run(SpringMethodRoadie.java:333)
at org.springframework.test.context.junit4.SpringMethodRoadie.runWithRepetitions(SpringMethodRoadie.java:217)
at org.springframework.test.context.junit4.SpringMethodRoadie.runTest(SpringMethodRoadie.java:197)
at org.springframework.test.context.junit4.SpringMethodRoadie.run(SpringMethodRoadie.java:143)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.invokeTestMethod(SpringJUnit4ClassRunner.java:160)
at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:97)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
And I got to this blog post on the net. http://thejavablog.wordpress.com/2008/05/21/orghibernatemappingexception-unknown-entity/
Now that explained everything: I shoudn’t use org.hibernate.annotations.Entity, but javax.persistence.Entity.
Isn’t that sweet ? For a newbie in Java it’s really hard to understand why Entity annotation which you do use at hibernate, shouldn’t be in org.hibernate.annotations.Entity, but instead in javax.persistence.Entity.
Well looks like java API coders don’t like logical and simple things. And another question when I should use org.hibernate.annotations.Entity? Do I really need it with the same name in this package?
Well may be someone on the Java side would explain this thing. That really would be nice.