Why doesn't hibernate load persisted entity from second level cache? - java

Does hibernate put into second level cache entity which I persist with save method?
My code is :
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Person person = new Person("Volodia", "Levytskyi", "Mykolaiv");
session.save(person);
transaction.commit();
session.close();
session = sessionFactory.openSession();
transaction = session.beginTransaction();
Person load = (Person) session.load(Person.class, (long) 1);
System.out.println("load2=" + load);
transaction.commit();
session.close();
I expect hibernate to load from second level cache person but it issues select query to database when
session.load(Person.class, (long) 1);
is running.
My hibernate.cfg.xml:
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernateSimpleDB</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password"></property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="transaction.factory_class">org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory</property>
<property name="hibernate.hbm2ddl.auto">create</property>
<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
<property name="hibernate.generate_statistics">true</property>
<property name="current_session_context_class">thread</property>
<mapping resource="com/masterhibernate/SimpleHibernateDemo/Person.hbm.xml"
/>
<!-- <mapping class="com.masterhibernate.SimpleHibernateDemo.Person" /> -->
</session-factory>
</hibernate-configuration>
My Person.hbm.xml :
<hibernate-mapping>
<class name="com.masterhibernate.SimpleHibernateDemo.Person"
table="Person">
<cache usage="read-write" />
<id name="id" column="PersonId">
<generator class="native" />
</id>
<property name="name">
<column name="name" length="16" not-null="true" />
</property>
<property name="surname">
<column name="surname" length="36"></column>
</property>
<property name="address">
<column name="address" length="22"></column>
</property>
</class>
</hibernate-mapping>
Why is this?

It seems like you have your database set up to generate primary keys for you. This means that, when you save the entity, it does not yet have an ID, as it will later be assigned by the database. This also means that hibernate cannot store it in the second-level cache, as it doesn't have a key to index it with yet. It should be stored in the second-level cache after retrieving it again from the database though.

Related

Hibernate SQL Error in generated query (Potentially a mapping mistake)

I'm making this simple app using Hibernate to do some CRUD operations. I'm having this error in the query generated by hibernate
Config XML:
<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/library</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123456</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.default_schema">library</property>
<property name="hbm2ddl.auto" value="create"/>
<!-- Mappings -->
<mapping resource="librarysystem/mappings/Role.hbm.xml"/>
<mapping resource="librarysystem/mappings/Librarian.hbm.xml"/>
<mapping resource="librarysystem/mappings/Task.hbm.xml"/>
<mapping resource="librarysystem/mappings/Library.hbm.xml"/>
</session-factory>
</hibernate-configuration>
POJO:
public class Library implements java.io.Serializable {
private int id;
private String name;
private Set librarians = new HashSet(0);
//Constructors, getters and setters...
}
Mapping:
<hibernate-mapping>
<class name="librarysystem.entities.Library" table="library" catalog="library" optimistic-lock="version">
<id name="id" type="int">
<column name="id" />
<generator class="assigned" />
</id>
<property name="name" type="string">
<column name="name" length="45" />
</property>
<set name="librarians" table="librarian" inverse="true" lazy="true" fetch="select">
<key>
<column name="libraryid" not-null="true" />
</key>
<one-to-many class="librarysystem.entities.Librarian" />
</set>
</class>
</hibernate-mapping>
Code to get the list:
List<Library> libraries = session.createQuery("FROM Library").list();
When I run a query to get the list of libraries, an exception occurs saying that the query syntax is wrong
the log output of the query is:
select
library0_.id as id1_2_,
library0_.name as name2_2_
from
library.library.library library0_
How did the library.library.library happened?
Any help please?
I've given the minimum details as I thought was necessary. If you need more code to find the error (like other POJOs and mappings), please inform me
How did the library.library.library happened? Any help please?
I'm no expert here but I think the tripple library here comes from the table being named library within a Database (catalog) named library.
<class name="librarysystem.entities.Library" table="library" catalog="library" optimistic-lock="version">
The table name and the catalog name are the same. So we are looking for a catalog called library library within which we want a table called library library.library. Although I'm not 100% on the third library, I think I'm in the right direction.
On a side note, I find it easier to work with hibernate annotation instead of xml mapping.
Difference between annotation and xml mapping in Hibernate
XML mapping example
Annotation example

Hibernate - org.hibernate.hql.internal.ast.QuerySyntaxException: Client is not mapped

I'm new to hibernate and I'm trying to solve some problems i cannot understand too well...
For example, I have this query
Query query = session.createQuery("from Client where clientId = "+clientId+")");
List result = query.list();
My Client.hbm.xml is
<class name="it.besmart.models.Client" table="client" catalog="SMARTPARK">
<id name="idClient" type="int">
<column name="id_client" />
<generator class="identity" />
</id>
<property name="nomeClient" type="string">
<column name="nome_client" length="65535" not-null="true" />
</property>
<property name="numPosti" type="int">
<column name="num_posti" not-null="true" />
</property>
<property name="numLuci" type="int">
<column name="num_luci" not-null="true" />
</property>
<property name="inizioPosti" type="int">
<column name="inizio_posti" not-null="true" />
</property>
<property name="inizioLuci" type="int">
<column name="inizio_luci" not-null="true" />
</property>
</class>
</hibernate-mapping>
The table on the DB is called client and the column is client_id
The mapping in hibernate.cfg.xml is
<hibernate-configuration>
<session-factory name="parkserver">
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.password">passwprd</property>
<property name="hibernate.connection.url">jdbc:mysql://192.168.3.67:3306/SMARTPARK</property>
<property name="hibernate.connection.username">parkuser</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<mapping class="it.besmart.models.Client" resource="Client.hbm.xml"/>
<mapping class="it.besmart.models.Illuminazione" resource="Illuminazione.hbm.xml"/>
<mapping class="it.besmart.models.MappaPosti" resource="MappaPosti.hbm.xml"/>
<mapping class="it.besmart.models.Occupazione" resource="Occupazione.hbm.xml"/>
</session-factory>
</hibernate-configuration>
I'm having no problems in another query in the application, but when i try to executer the SELECT query i got this exception
org.hibernate.hql.internal.ast.QuerySyntaxException: Client is not mapped [from Client where clientId = 1)]
at org.hibernate.hql.internal.ast.QuerySyntaxException.generateQueryException(QuerySyntaxException.java:79)
at org.hibernate.QueryException.wrapWithQueryString(QueryException.java:103)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:218)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:142)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:115)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:76)
at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:150)
at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:298)
at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:236)
at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1836)
at it.besmart.parkserver.SocketClientHandler.run(SocketClientHandler.java:83)
at java.lang.Thread.run(Thread.java:744)
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: Client is not mapped
at org.hibernate.hql.internal.ast.util.SessionFactoryHelper.requireClassPersister(SessionFactoryHelper.java:171)
at org.hibernate.hql.internal.ast.tree.FromElementFactory.addFromElement(FromElementFactory.java:91)
at org.hibernate.hql.internal.ast.tree.FromClause.addFromElement(FromClause.java:76)
at org.hibernate.hql.internal.ast.HqlSqlWalker.createFromElement(HqlSqlWalker.java:321)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElement(HqlSqlBaseWalker.java:3678)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElementList(HqlSqlBaseWalker.java:3567)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromClause(HqlSqlBaseWalker.java:708)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:564)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:301)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:249)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:262)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:190)
I don't know why Client is not mapped, it's correctly in the cfg file...
Thanks in advance
Try to add the full name of the class in the query:
Query query = session.createQuery("from it.besmart.models.Client where clientId = :c");
query.setString("c", clientId)
List result = query.list();
I also changed to late binding here which is preferable but has nothing to do with your problem.
As Maurice Perry pointed out in comment below:
- You can also specify the default package in the mapping file: <hibernate-mapping package="it.besmart.models">

java.lang.NoSuchMethodError when closing Hibernate Session in Java Swing application

I am getting this error:
Exception in thread "AWT-EventQueue-0" java.lang.NoSuchMethodError: org.hibernate.Session.close()Ljava/sql/Connection;
When calling this function:
private static SessionFactory factory;
public static void insert(Object model) {
factory = new Configuration().configure().buildSessionFactory();
Session session = factory.openSession();
Transaction tx = session.beginTransaction();
try {
session.save(model);
tx.commit();
} catch (HibernateException exc) {
if (tx != null)
tx.rollback();
exc.printStackTrace();
} finally {
session.close(); // here is when the error occurs
}
}
I believe I have imported all the necessary jars from /lib/required/ directory in the latest Hibernate 5.0.1.
The hibernate.cfx.xml file is also correctly configured:
<?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="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:3307/test</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.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.classic.ClassicQueryTranslatorFactory</property >
<mapping resource="customer.hbm.xml"/>
</session-factory>
</hibernate-configuration>
And customer.hbm.xml mapping file:
<class name="com.test.app.model.Customer" table="customer">
<meta attribute="class-description">
Test.
</meta>
<id column="id" name="id" type="int">
<generator class="native"/>
</id>
<property name="name" column="name" type="string"/>
<property name="phoneNumbers" column="phone_numbers" type="string"/>
<property name="emailAddresses" column="email_addresses" type="string"/>
<property name="address" column="address" type="string"/>
<property name="note" column="note" type="string"/>
</class>
What could be the issue?
Looks like you have two hibernate-core-5.0.1.Final.jar in your classpath. For example, if you run a project in the IDE and add other project with hibernate-core-5.0.1.Final.jar to your classpath.
P.S. Please don't configure the session factory in every insert, and rollback on any exception, not only on HibernateException. You can see how properly working with transactions here, and you can find a simply example console project using Hibernate 5 and MySQL here.

Empty collection after hibernate select

I want find all records in table 'users' using hibernate but its allways return empty collection (im sure that some users are in db). My searching function looks like this:
public List<Users> findAll() {
DetachedCriteria criteria = DetachedCriteria.forClass(Users.class);
return getHibernateTemplate().findByCriteria(criteria);
}
Why is not working?
hibernate.cfg.xml:
<hibernate-configuration>
<session-factory>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/intellidom</property>
<property name="connection.username">root</property>
<property name="connection.password"></property>
<mapping file="mapping/Users.hbm.xml"/>
</session-factory>
</hibernate-configuration>
Users.hbm.xml:
<hibernate-mapping>
<class name="intellidom.entity.Users" table="users" schema="intellidom">
<id column="id" name="id" type="int" >
<generator class="increment"/>
</id>
<property name="login" column="login" type="java.lang.String"/>
<property name="password" column="password" type="java.lang.String"/>
<property name="firstName" column="firstName" type="java.lang.String"/>
<property name="lastName" column="lastName" type="java.lang.String"/>
</class>
</hibernate-mapping>

Exception in thread "main" org.hibernate.MappingException: Unknown entity: from Destination

I am learning hibernate and I can't figure out why is this error popping up. I tried searching but I couldn't find a solution that helped me. I'd like to learn why am I getting this error.
Exception in thread "main" org.hibernate.MappingException: Unknown entity: from Destination
Here are some details:
main():
public static void main(String[] args) {
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
// Destination destination = new Destination();
// destination.setName("IDelhi");
// destination.setLatitude(1.0f);
// destination.setLongitude(123.0f);
// session.save(destination);
List result = session.createCriteria("from Destination").list();
session.getTransaction().commit();
session.close();
// for (Object dest : result) {
// Destination d = (Destination)dest;
// System.out.println(d.getId() + ": "+ d.getName());
// }
}
}
When I try to insert the destination (commented code), values are being inserted into db.
Configurations:
hibernate.cfg.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 name="">
<property name="hibernate.connection.driver_class">org.gjt.mm.mysql.Driver</property>
<property name="hibernate.connection.password">*****</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/</property>
<property name="hibernate.connection.username">*****</property>
<property name="hibernate.default_schema">wah_schema</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<mapping class="org.wah.dao.Destination" resource="org/wah/dao/Destination.hbm.xml"/>
</session-factory>
</hibernate-configuration>
Destination.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Jan 25, 2012 3:31:00 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="org.wah.dao.Destination" table="DESTINATION">
<id name="id" type="int">
<column name="ID"/>
<generator class="identity"/>
</id>
<property generated="never" lazy="false" name="name" type="java.lang.String">
<column name="NAME"/>
</property>
<property generated="never" lazy="false" name="latitude" type="float">
<column name="LATITUDE"/>
</property>
<property generated="never" lazy="false" name="longitude" type="float">
<column name="LONGITUDE"/>
</property>
</class>
</hibernate-mapping>
Can someone please help me figure this out ?
use session.createCriteria(Destination.class); You are trying to use HQL - Hibernate Query Language for which you need to use other api like
Query query = session.createQuery("from Destination");
List list = query.list();
<mapping class="org.wah.dao.Destination"
resource="org/wah/dao/Destination.hbm.xml"/>
instead of this, please change it to
<mapping resource="org/wah/dao/Destination.hbm.xml">
Hibernate throws this error because when it expect some Annotation based class, you are referring the XML based Hibernate mapping. Stick to two different rule Annotations or XML based.
You are mixing HQL and Criteria query. You should either do
session.createCriteria(Destination.class).list();
or
session.createQuery("from Destination").list();
According to here, something like this should work:
List result = session.createCriteria(Destination.class).list();
I had similar problem for a simple Console application trying to use Hibernate. The solution I arrived to make the add the "packagesToScan" property explicitly for LocalSessionFactoryBean.
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="com.mg.learning.spring.orm"/> <--- this SOLVED!
<property name="hibernateProperties">
<props>
<prop key="dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
</props>
</property>
</bean>

Categories

Resources