I'm getting a bizarre Hibernate exception that I can't explain. It's telling me that I'm using 2nd level cache, but no where in hibernate.cfg.xml do I specify a 2nd level cache. Here's the exception:
org.hibernate.cache.NoCacheRegionFactoryAvailableException: Second-level cache is used in the
application, but property hibernate.cache.region.factory_class is not given, please either
disable second level cache or set correct region factory class name to property
hibernate.cache.region.factory_class (and make sure the second level cache provider,
hibernate-infinispan, for example, is available in the classpath).
at org.hibernate.cache.internal.NoCachingRegionFactory.buildEntityRegion(NoCachingRegionFactory.java:69)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:348)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1769)
at net.me.myapp.common.dao.SessionFactoryProvider.newSessionFactory(SessionFactoryProvider.java:37)
at net.me.myapp.common.dao.BaseDAO.doPersist(BaseDAO.java:28)
at net.me.myapp.common.dao.WordDAO.deleteAllWords(WordDAO.java:36)
at net.me.myapp.tools.dmapper.DictionaryMapper.run(DictionaryMapper.java:88)
at net.me.myapp.tools.dmapper.DictionaryMapper.main(DictionaryMapper.java:56)
And my hibernate.cfg.xml:
<?xml version='1.0' encoding='UTF-8'?>
<!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>
<!-- DataSource & Connection info. -->
<property name="hibernate.dialect">org.hibernate.dialect.H2Dialect</property>
<property name="hibernate.connection.driver.class">org.h2.Driver</property>
<property name="hibernate.connection.url">jdbc:h2:file:/${MYAPP_HOME}/data/myapp</property>
<property name="hibernate.connection.username">myapp</property>
<property name="hibernate.connection.password">mypassword</property>
<property name="hibernate.connection.pool_size">1</property>
<!-- General Hibernate settings. -->
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="use_sql_comments">true</property>
<!-- DDL Mode. -->
<property name="hbm2ddl.auto">validate</property>
<!-- All our Hibernate mapping XML files. -->
<mapping class="net.me.myapp.common.dto.WordDTO" />
</session-factory>
</hibernate-configuration>
Any ideas what would be triggering this exception? Thanks in advance!
Pau wrote on hibernate.cache.region.factory_class Required in hibernate.cfg.xml:
The exception is quite self-explanatory. You have to set the
hibernate.cache.region.factory_class property. For instance with ehcache would be adding the following line:
<property name="hibernate.cache.region.factory_class">net.sf.ehcache.hibernate.EhCacheRegionFactory</property>
Using the following line fixed it :
<beans:entry key="hibernate.cache.use_second_level_cache" value="false"/>
But the Hibernate message is probably a warning that we should use second level cache?
I also received this error and took me a while to track down. At one point we were going to have multiple cache regions, but in the end decided we were just going to have one cache pool.
When we merged that change into an older branch - we still had an entity with the old strategy of a cache pool per entity:
#Entity
#Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region="tableRegion")
#Table(name = "table")
public class table {
By removing the Cache annotation - it resolved the org.hibernate.cache.NoCacheRegionFactoryAvailableException:
#Entity
#Table(name = "table")
public class table {
Figured I'd post in case anyone else had a similar situation
This error is very misleading, I spent almost a day to finally figure out the root cause. Thought my hibernate config file has defined second level cache and factory class, it was giving me error that hibernate.cache.region.factory_class is not given.
I see that by hibernate.cfg.xml file is also available in classpath. But even after any change in that there was no impact and getting same error.
Finally I realized that for test purpose I have overridden persistence.xml file which has below missing properties under persistence-unit. After adding that issue was resolved.
<properties>
<property name="hibernate.ejb.cfgfile" value="hibernate.cfg.xml" />
</properties>
So this means my application was not able to find hibernate.cfg.xml file and somehow instead of giving error related to missing configuration, it cries out for factory class.
These are the property you need to add to enable second level cache
<!-- Provider for second level cache -->
<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
Related
I have been trying my hand to implement hibernate using a small example.
Below is my hibernate.config.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.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="connection.url">
jdbc:mysql://localhost:3306/abc
</property>
<property name="connection.username">root</property>
<property name="connection.password"></property>
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="show_sql">true</property>
<mapping
resource="HibernateExample/src/HibernateExposed/Resource/Person.hbm.xml"/>
</session-factory>
</hibernate-configuration>
When running the code I am getting error org.hibernate.boot.MappingNotFoundException: Mapping (RESOURCE) not found.
I tried replacing mapping as below
<mapping
resource="Resource/Person.hbm.xml"/>
and also tried to keep the mapping xml at same location as hibernate.config.xml.
<mapping
resource="Person.hbm.xml"/>
Under none of above mentioned cases, code can find my Person.hbm.xml.
My folder structure looks as below
I looked at all other answers for this error on Stackoverflow but none of the approaches resolved this issue. Any help is highly appreciated. Also, is there any approach to debug this further to granular level?
Please, put hibernate.cfg.xml in the root of src folder.
And use
<mapping resource="HibernateExposed/Person.hbm.xml"/>
Hibernate loads all those files using ClassLoader.getResourceAsStream(resourcePath) resourcePath — is the path to the file
ClassLoader tries to get access to the files in the root of bin or build folder in the IDE, or root of jar, or root of war/WEB-INF/classes/ for web-applications. Those all are the root of the class path.
bin is a folder where Eclipse compiles your files. The root of src folder is compiled to the root of bin folder. You can check it.
For an example
configure("hibernate.cfg.xml") — bin/hibernate.cfg.xml configure("xxx/hibernate.cfg.xml") — bin/xxx/hibernate.cfg.xml
<mapping resource="HibernateExposed/Person.hbm.xml"/>
corresponds bin/HibernateExposed/Person.hbm.xml
A path should be without the leading / for a ClassLoader. Hibernate tries to delete the leading /.
A path like this is valid too
<mapping resource="/HibernateExposed/Person.hbm.xml"/>
Update
You can specify path to the hibernate.cfg.xml, if you don't want to have it in the root
new Configuration().configure("HibernateExposed/hibernate.cfg.xml")
if you use
new Configuration().configure()
it should be in the root of the class path.
none of this worked for me, then I tried this:-
(replace this method in FactoryConfiguration singleton Class)
private FactoryConfiguration() {
Configuration configuration = new Configuration().configure("hibernate.cfg.xml").addAnnotatedClass(***Class Name***.class);
sessionFactory = configuration.buildSessionFactory();
}
I am new bee to Hibernate and trying out things.
One thing that seems to amuse all is how to connect to different databases?
I have two questions here:
If in the same web app I need to connect to MySQL and Oracle, how do I do it?
I am using MySQL and have two databases test1 and test2, how to connect and retrieve data?
I have read in a blog that we can create different configuration files and do it.
I tried it but was not sucessful.
Here's what I tried:
SessionFactory sf = (SessionFactory) new Configuration().configure(path);
Where path is the path of the config file.
Is this the right way?
Using annotation mappings as an example:
Configuration cfg1 = new AnnotationConfiguration();
cfg1.configure("/hibernate-oracle.cfg.xml");
cfg1.addAnnotatedClass(SomeClass.class); // mapped classes
cfg1.addAnnotatedClass(SomeOtherClass.class);
SessionFactory sf1 = cfg1.buildSessionFactory();
Configuration cfg2 = new AnnotationConfiguration();
cfg2.configure("/hibernate-mysql.cfg.xml");
cfg2.addAnnotatedClass(SomeClass.class); // could be the same or different than above
cfg2.addAnnotatedClass(SomeOtherClass.class);
SessionFactory sf2 = cfg2.buildSessionFactory();
Then use sf1 and sf2 to get the sessions for each database. For mapping files, you just use cfg.addClass instead of addAnnotatedClass. Put the cfg.xml files in the root package in this case. Those will have the Oracle or MySQL dialect and connection information.
It cannot be done using one hibernate configuration file. You need to have two configurations files for it.
To configure mysql database
hibernate-mysql.cfg.xml
To configure oracle database
hibernate-oracle.cfg.xml
In Details, mysql configuration file be like this.
<?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.bytecode.use_reflection_optimizer">false</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.password">PASSWORD</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/UR_DB_NAME</property>
<property name="hibernate.connection.username">USERNAME</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
<mapping class="domain.EmployeeMysql"></mapping>
</session-factory>
</hibernate-configuration>
In Details, oracle configuration file be like this.
<?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.bytecode.use_reflection_optimizer">false</property>
<property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="hibernate.connection.password">PASSWORD</property>
<property name="hibernate.connection.url">jdbc:oracle:thin:UR DB NAME</property>
<property name="hibernate.connection.username">USERNAME</property>
<property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>
<property name="show_sql">true</property>
<mapping class="domain.EmployeeOracleSql"></mapping>
</session-factory>
</hibernate-configuration>
And code should be like this.
mysql configuration
private static SessionFactory sessionAnnotationFactory;
sessionAnnotationFactory = new Configuration().configure("hibernate-mysql.cfg.xml").buildSessionFactory();
Session session = sessionAnnotationFactory.openSession();
oracle sql configuration
sessionAnnotationFactory = new Configuration().configure("hibernate-oracle.cfg.xml").buildSessionFactory();
Session session = sessionAnnotationFactory.openSession()
Ideally you should move to Distributed transaction type of system[using Java Transaction Analyzer org.hibernate.transaction.JTATransactionFactory] in this case. If you are running in JBoss App Server, you can do it by using "Distributed Transaction Managers". You can learn more about it here.
You can also use a catalog with the value of the other database
#Table(name = "foo", schema = "bar", catalog = "OtherDatabase")
You can also Add mapping class in configuration.xml file
Note : this is for annotations and for resources use resources keyword instead of class
<mapping class="packageName.classNmae1"/>
<mapping class="packageName.classNmae2"/>
You can connect two databases test1 and test2, retrieve data with only one hibernate with some tricks:
hibernate SQLQuery: just add database name with the table "select * from test1.table1", "select * from test2.table2"
hibernate persistence: using the key schema in the hibernate mapping xml
<class name="Table1Class" table="table1" schema="test1">
<class name="Table2Class" table="table2" schema="test2">
I am working with Hibernate on Java with a MySQL database. If I set hbm2ddl.auto to create`, all current tables are dropped and recreated correctly, but if I set it to "update" it does nothing to the database despite reporting the following line to the console:
INFO: HHH000228: Running hbm2ddl schema update
For reference, the code I am using to set up the database is:
final StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
.configure()
.build();
While my cfg.xml file looks like:
<?xml version='1.0' encoding='utf-8'?>
<!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>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://127.0.0.1:3306/testdatabase</property>
<property name="connection.username">xxxxxxxx</property>
<property name="connection.password">xxxxxxxx</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">update</property>
<!-- Names the annotated entity class -->
<mapping class="com.test.case.Example"/>
</session-factory>
</hibernate-configuration>
Obviously since the create is working, I see no need to show my annotated class.
Edit:
The changes I expect to happen are basically to correct the database column types to the correct ones. Before running the update I change the column types in MySql to something different from the annotated schema but on update it's not correcting it as would be expected. In contrast when I dropped the table altogether the update did work, it would seem update is not as fully featured as expected?
Service registry requires some properties from the configuration. And because you are using non-standard name/location of the hibernate configuration file
final StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
.configure("cfg.xml")
.build();
I have a project using JBoss + hibernate, and NOT JPA (don't ask me why, just assume this way). So we're using hibernate.cfg.xml and hibernate Session. Well, I'm trying to make JBoss to handle my session, so I changed my hibernate.cfg.xml to something like this:
<hibernate-configuration>
<session-factory name="unitName">
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">false</property>
<property name="hibernate.connection.datasource">MyDS</property>
</session-factory>
</hibernate-configuration>
And in my code I just added:
#PersistenceContext(unitName="unitName") protected Session session;
But when I run the application, it goes:
Caused by: java.lang.IllegalArgumentException: Can't find a persistence unit named 'unitName' in ...
Tried changing from hibernate.cfg.xml to persistence.xml, but still using Session, and I got an error similar to this: https://issues.jboss.org/browse/JBAS-8815
I know, there is a workaround for this error, but my main question is: Can I use a managed Datasource with plain Hibernate/Session and hibernate.cfg.xml? What I'm doing wrong?
Thanks!
I'm using Embedded Derby DB with hibernate. I'm saving some entities to database. After shutting down the application there is no entities in DB. Why it could be so?
Below my Hibernate configuration
<?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="show_sql">true</property>
<property name="format_sql">true</property>
<property name="dialect">org.hibernate.dialect.DerbyDialect</property>
<property name="connection.driver_class">org.apache.derby.jdbc.EmbeddedDriver</property>
<property name="connection.url">jdbc:derby:\bases\localbase;create=true</property>
<property name="connection.username"></property>
<property name="connection.password"></property>
<property name="hibernate.hbm2ddl.auto">validate</property>
<mapping class="com.example.model.HistoryItem"/>
<mapping class="com.example.model.User"/>
<mapping class="com.example.model.BaseAbstractEntity"/>
</session-factory>
</hibernate-configuration>
This is weird because Derby sync to the disk after each commit by default (unless you set the property derby.system.durability=test). And your url looks correct (although I would use forward slashes).
This begs the question: how do you managed transactions? Are you sure that you are committing them?
Derby likes to hang on to the data - ie keep it in memory. If you try shutting it down by trying something like:
DriverManager.getConnection("jdbc:derby:;shutdown=true");
This should make sure the data is flushed to the disk and derby is shut down cleanly.
At the moment I am trying to get Hibernate 3.6 to do this for me - no luck so far.
Perhaps you are looking in the wrong place. Perhaps the Hibernate application is creating a Derby database in one location on your hard disk, but when you look for the database contents later, you are looking in a different location on your hard disk. Since your Derby URL says "create=true", Derby will quietly create a new empty database for you if you don't get exactly the same location specification as in your original app.