Hibernate Annotations

2AndAHalfBit

Aktives Mitglied
Hallo zusammen,

ich glaub ich nerve oder? Sorrrry dafür...
Weil OpenJPA mit dem Tomcat nicht funktionierte, bin ich nun zu Hibernate gewechselt.

Softwaretechnische Infrastruktur:
  • Tomcat 7
  • Java SE
  • Apache MyFaces
  • Hibernate für den Datenzugriff

Problem:
Ich habe eine relativ simple Webanwendung. Wenn ich ohne Annotations arbeite (Class.hbm.xml), dann funktioniert alles. Wenn ich mit Annotationen arbeite, erhalte ich beim Speichern folgende Exception:

org.hibernate.MappingException: Unknown entity: de.jdoit.application.Task
at org.hibernate.internal.SessionFactoryImpl.getEntityPersister(SessionFactoryImpl.java:1028)
at org.hibernate.internal.SessionImpl.getEntityPersister(SessionImpl.java:1270)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:119)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:204)
at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:55)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:189)
at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:49)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:642)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:635)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:631)
at de.jdoit.persistence.HibernatePersistenceManager.saveTask(HibernatePersistenceManager.java:32)

Da es noch ein kleines Projekt ist, poste ich mal den Code.
Alle required libs sind sowohl im WEB-INF/libs als auch in TOMCAT_HOME/libs deployed.

[xml]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.url">jdbc:mysql://localhost/JDOIT-DB</property>
<property name="connection.username">myuser</property>
<property name="connection.password">somekeyword</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>

<property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
<property name="current_session_context_class">thread</property>
<property name="hibernate.show_sql">true</property>

<mapping package="de.jdoit.application" class="Task" />
</session-factory>
</hibernate-configuration>
[/xml]

Die Bean
Java:
package de.jdoit.application;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.Size;

import org.hibernate.annotations.GenericGenerator;


@Entity
@Table(name = "JdoTask")
public class Task
{

	@Id
	@GeneratedValue(generator="increment")
	@GenericGenerator(name="increment", strategy = "increment")
	private int id;
	
	@Column(name="taskname")
	private String name;
	
	@Column(name="taskhelp")
	private String description;

	@Id
	@GeneratedValue(generator="increment")
	@GenericGenerator(name="increment", strategy = "increment")
	public int getId()
	{
		return id;
	}

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

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

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

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

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

Der Managed Bean für die Webseite:
Java:
package de.jdoit.web;
import java.util.ArrayList;

import javax.faces.bean.ManagedBean;

import de.jdoit.application.Task;
import de.jdoit.interfaces.JDOITPersistenceManager;
import de.jdoit.persistence.HibernatePersistenceManager;
import de.jdoit.persistence.OpenJPAPersistenceManager;


@ManagedBean
public class JDOSessionBean {
	
	private ArrayList<Task> tasks;
	private JDOITPersistenceManager persistanceManager;

	
	public ArrayList<Task> getTasks() {
		return tasks;
	}

	public void setTasks(ArrayList<Task> tasks) {
		this.tasks = tasks;
	}
	
	public JDOSessionBean()
	{
		persistanceManager = new HibernatePersistenceManager();
		tasks = new ArrayList<>();
	}
	
	
	public String createTask()
	{
		
		Task task = new Task();
		task.setName("Defaultname");
		task.setDescription("this task is for testing purpose only.");
		
		persistanceManager.saveTask(task);
		
		return "index";
	}
}

Der Persistence Layer
Java:
package de.jdoit.persistence;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import de.jdoit.application.Task;
import de.jdoit.interfaces.JDOITPersistenceManager;

public class HibernatePersistenceManager implements JDOITPersistenceManager
{
	@SuppressWarnings("unused")
	private Session getSessionFactory(boolean openNewSession)
	{
		Configuration config = new Configuration();
		SessionFactory sessionFactory = config.configure().buildSessionFactory();
		
		if(openNewSession)
			return sessionFactory.openSession();
		else 
			return sessionFactory.getCurrentSession();
		
	}

	@Override
	public void saveTask(Task task)
	{
		Session s = this.getSessionFactory(true);
		s.beginTransaction();
		s.save(task);
		s.getTransaction().commit();
		s.close();
	}
}
 
Hi,

EDIT:
Schwachfug. Sehe gerade du verwendest ja <mapping package>... müsste also funktionieren. Mein restlicher Beitrag wird dadurch quasi hinfällig. Es sei denn du willst es mal mit der programmatischen Variante versuchen...


Ich bin mir ziemlich sicher, daß man einmal alle Entity Klassen Hibernate mitteilen muss. Entweder in der *.xml wo du die Session Factory deklarierst. Ich meine da wo du <session-factory> benutzt: z.B: <mapping class="de.jdoit.application.Task />

Oder programmatisch beim Erzeugen des Configuration Objektes:
Java:
new Configuration().addAnnotatedClass(Task.class).addAnnotatedClass(eineAndereKlasse.class).configure().buildSessionFactory();

Ich meine mit einer neueren Hibernate Version müsste der programmatische Weg so funktionieren. Bei älteren müsstest du wahrscheinlich statt Configuration() AnnotationConfiguration() verwenden.

Mein letztes Hibernate Projekt liegt etwas zurück, darum alle Angaben ohne Gewähr 😉
Google Stichwörter wären 'hinernate mapping class' und/oder 'AnnotationConfiguration'.

Gruß
 
Zuletzt bearbeitet:
Hallo,

eigentlich logisch. Hätte ich auch selbst drauf kommen können.

Aber: Eine Frage dazu. Ich habe die Hibernatelibs nun auch in WEB-INF/lib gepackt und damit geht es.
Habt ihr eine Erklärung dafür?

Btw.: Wäre schön wenn mir jemand erklären könnte, wann im eine Lib ins Tomcatlib-Verzeichnis muss und wann es reicht, sie im war in WEB-INF/lib zu deployen...

Grüße, und danke für eure Hilfe.
 
Danke für Eure Hilfe.
Ich habe die Libs aus dem Tomcat wieder rausgeholt und nun funktioniert es.

Eine Frage aber noch: Die Entity muss sie Serializable sein?
Wenn ja, verstehe ich nicht, warum es funktioniert...

Grüße
 
Eine Frage aber noch: Die Entity muss sie Serializable sein?
Wenn ja, verstehe ich nicht, warum es funktioniert...
Seit Version 4.0 ist das keine ganz so starre Forderung mehr. Deswegen gibt es in Deinem Fall wohl keine Probleme. Soweit ich die Spec verstanden habe, müssen Entities nur noch dann Serializable sein, wenn sie von einem EJB Remote Interface returned werden (was immer das ist, kenne mich mit EJB nich so aus). Bei den älteren Versionen von Hibernate gab's aber des öfteren Exceptions, wenn man das Serializable vergessen hatte. Probier halt aus, ob Du damit Probleme bekommst.

Die Hibernate-Doku empfiehlt übrigens für id-Properties nullable Types und keine primitives zu nehmen (HIBERNATE - Relational Persistence for Idiomatic Java).
 

Zurück
Oben