Hi,
First of all, I know, that there are several similar questions on both - here and StackOverflow. However, none of those helped me and I spent on this almost half day…
I’ve been programming native/vanilla Hibernate years ago… and now I decided to recall/recover the knowledge which I basically don’t need anymore, but I’m really interested in it. So, I took a short course on Hibernate
, which I followed clearly and accordingly. Now, I’m supposed to have one hibernate.cfg.xml
file for basic configuration for the database, and also one MyClass.hbm.xml
for mapping. I then include that hbm
file into hibernate.cfg.xml
as a declared mapping element; however, I was getting the exception of the title of this question. Finally, only after I annotated class with @Entity, @Id, @GeneratedValue(strategy=GenerationType.IDENTITY)
AND after I passed hibernate.cfg.xml
file into Configuration
's constructor and added .addAnnotatedClass(package.ClassName)
to my Configuration
object, it finally worked. I believe that the crucial part was this addAnnotatedClass
I presume, that now, annotations work for mapping, and not .hbm.xml
file.
The code is below. Could anyone explain to me why hbm didn’t work (still doesn’t work), and whether I can make it work? I understand that it might be deprecated style (same as everywhere… people get rid of xml), but still… wondering why it did work for instructor and didn’t work for me - when I just copy pasted her work.
Thank you!
Main class
package com.giorgi.app
public class MainClass {
private static SessionFactory sessionFactory;
private static ServiceRegistry serviceRegistry;
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter message: ");
String message = input.nextLine();
try {
/* This is my code and it works..
Configuration conf = new Configuration()
.configure("hibernate.cfg.xml")
.addAnnotatedClass(com.giorgi.model.Message.class); */
Configuration conf = new Configuration().configure(); //this is in lecture, and this doesn't work.
serviceRegistry = new StandardServiceRegistryBuilder().applySettings(conf.getProperties()).build();
sessionFactory = conf.buildSessionFactory(serviceRegistry);
} catch (Throwable throwable) {
System.err.println("Failed to create a Session Factory object" + throwable);
throw new ExceptionInInitializerError(throwable);
}
Session session = sessionFactory.openSession();
Transaction transaction = null;
Short msgId = null;
try {
transaction = session.beginTransaction();
//Storing 1000 records. Note, that if you'll instantiate object outside of loop and only put .save(m) into loop, object won't be stored 1000 times.. probably hash is considered and Hibernate knows that it's same object.
Message m = null;
for (int i = 0; i < 1000; i++) {
m = new Message(message+" "+i);
msgId = (Short) session.save(m);
}
List messages = session.createQuery("FROM Message").list();
for (Object msg : messages) {
System.out.println("Message " + ((Message) msg).getMessage());
}
transaction.commit();
} catch (HibernateException e) {
if (transaction != null) {
transaction.rollback();
e.printStackTrace();
}
} finally {
session.close();
}
StandardServiceRegistryBuilder.destroy(serviceRegistry);
}
}
Entity class
package com.giorgi.model;
public class Message implements java.io.Serializable { //also, in the lecture, the class doesn't implement Serializable.
private Short id;
private String message;
public Message() {
}
public Message(String m) {
this.message = m;
}
public Short getId() {
return id;
}
public void setId(Short id) {
this.id = id;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
hibernate.cfg.xml
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernatecourse</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">password</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.query.factory_class">org.hibernate.hql.internal.classic.ClassicQueryTranslatorFactory</property>
<property name="hibernate.current_session_context_class">org.hibernate.context.internal.ThreadLocalSessionContext</property>
<!--
<mapping class="com.giorgi.model.Message"/> <- this works for @Entity annotation
-->
<mapping resource="Message.hbm.xml"/> <!--this is in lecture, and doesn't work-->
</session-factory>
</hibernate-configuration>
Message.hbm.xml
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.giorgi.model.Message" table="message" catalog="hibernatecourse">
<id name="id" type="java.lang.Short">
<column name="id"/>
<generator class="identity"/>
</id>
<property name="message" type="java.lang.String">
<column name="message" length="50"/>
</property>
</class>
</hibernate-mapping>
Directory structure is the Standard Maven Directory Layour and xml
files are in src/main/resources
.
Thank you, again!