Not able to get session factory in hibernate - java

try
{
System.out.println("openTxCoreSession() start...");
TxCoreSessionFactory sessionFactory =
TxCoreSessionFactory.getInstance("txcore.cfg.xml");
System.out.println("Session factory created....");
Session session = sessionFactory.openSession();
System.out.println("session created");
return session;
}
catch (Exception e)
{
System.out.println(e.getMessage());
e.printStackTrace();
return null;
}

Hibernate is not easy to start off with, does take a bit of time/effort.
Found one blog to get started with Hibernate, http://www.myeclipseide.com/documentation/quickstarts/hibernateintroduction/. But MyEclipse is a priced product. So personally I had to skip it for now.
I researched more and got Hibernator. Tried Hibernator which is a eclipse plugin to make Hibernate integration super easy (seemed too good to be true), but turned out to be a disaster. Gave it up. Also noticed that the code was as old as 2006, no one working on it now.
Then moved to Hibernate Tools from JBoss Hibernate Tools – http://download.jboss.org/jbosstools/updates/JBossTools-3.1.0.GA worked like a charm.
For people who are confused, MyEclipse or JBoss Hibernate Tools, its no different.
The main reason to use Hibernate on a server platform is to get rid of the complex JDBC hell hole. The only reason you thought you needed a object relational mapping solution was to get some neatness in code and good old re-usability built into the design.
Also the below works for me.
if (sessionFactory == null) {
try {
String jdbcProperty = "jdbc:mysql://"+Globals.DBSERVER+"/MyDB" ;
Configuration configuration = new Configuration().configure() ;
sessionFactory = configuration.buildSessionFactory(new ServiceRegistryBuilder()
.buildServiceRegistry());
} catch (Exception e) {
log.fatal("Unable to create SessionFactory for Hibernate");
log.fatal(e.getMessage());
log.fatal(e);
e.printStackTrace();
}
}
Hibernate.properties in the src folder of my eclipse project.
hibernate.connection.driver_class=com.mysql.jdbc.Driver
hibernate.connection.url=jdbc:mysql://localhost/MyDB
hibernate.connection.username=MYROOT
hibernate.connection.password=myPASSWORD
hibernate.connection.pool_size=2
hibernate.dialect=org.hibernate.dialect.MySQLInnoDBDialect
Also ensure that your configuration xml file (txcore.cfg.xml) is in the classpath of your application.

Related

Hibernate SessionFactory, setTransactionIsolationLevel on the fly

So,
The hibernate SessionFactory is available.
Now, on java.sql.Connection there is a method connection.setTransactionIsolation.
Now, from sessionFactory you can openSession(), or getCurrentSession()
From there, we can do:
session.doWork(connection -> { ... connection.setTransactionIsolation ... } )
However, my memory tells me this is already too late.
One actually needs to do connection.setTransactionIsolation likely before the Session has even been created.
Is this not true?
Further, setReadOnly has the same requirements.
Now, to get the connection before the session is created there is this answer:
https://stackoverflow.com/a/29844998/961018
But that requires the datasource.
So is there anyway one, can get the datasource from SessionFactory, so I can create this logic from what I currently have?
EDIT
RESPECTFULLY, DO NOT UTTER THE WORDS S.P.R.I.N.G or A.N.N.O.T.A.T.I.O.N.S.
The "Transaction Isolation" property has got a "Connection" level, that's why you have to apply it once creating the connection and not at transaction level or (like general rule for all connection) on SessionFactory.
Considering what you are trying to do, you have actually two different options to set the transaction isolation.
The most used, clean and recommended one is by setting the specific hibernate property, like following one:
<property name="hibernate.connection.isolation">2</property>
On the specific case, value 2 correspond "READ COMMITTED".
Otherwise, you could try to get the connection instance from the Session, like following code:
Session session = sessionFactory.getSession();
try {
session.connection().setTransactionIsolation(2);
} catch (HibernateException | SQLException e) {
e.printStackTrace();
}
Please bear in mind that the above is quite a dirty way to do that and it's not guarantee that it works. Moreover the method connection() of org.hibernate.Session is deprecated, so you should not use it.
However, I personally used for some unit tests (as an experiment) and it worked fine.

Tomee dynamic Resources/Datasources

After searching for a while, I'm exhausted and hope you can help me. I've been trying to write a Java EE application that comes with a datasource configurator (like WordPress at first startup). The datasources are not known on deploy time. With the router example of TomEE I found a method to dynamically replace datasources at application lifetime. I'm currently generating my datasources with the following code:
GeronimoTransactionManager transactionManager = (GeronimoTransactionManager) OpenEJB.getTransactionManager();
Properties props = new Properties();
props.setProperty("driverClassName", "com.mysql.cj.jdbc.Driver");
props.setProperty("url", "jdbc:mysql://localhost/test");
props.setProperty("password", "test");
props.setProperty("passwordCipher", "PlainText");
props.setProperty("username", "test");
try {
DataSource underlying = new org.apache.tomcat.jdbc.pool.DataSourceFactory().createDataSource(props);
dataSource = new ManagedDataSource(underlying, transactionManager, transactionManager);
} catch (Exception e) {
e.printStackTrace();
}
My problem is that at this point no ddl-generation is executed, so that entitymanager.persist(object); throws an exception that the table was not generated.
The following code produces an java.lang.AbstractMethodError:
Map properties = new HashMap<>();
StringWriter create = new StringWriter();
properties.put("javax.persistence.schema-generation.scripts.action", "create");
properties.put("javax.persistence.schema-generation.scripts.create-target", create);
Persistence.generateSchema("router", properties);
Is there a not "hacky" Java EE way to dynamically load resources, especially datasources. If not, is there a TomEE way? Thanks in advance.

Hibernate - open sessions vs current sessions and current session context

I have a spring managed web app where we're using Hibernate. In my hibernate.cfg.xml we have
<property name="hibernate.current_session_context_class">thread</property>
It's also configured to use HikariCP connection pooling.
When we open sessions, we follow the paradigm of this. Note that I'm not explicitly closing the session.
Transaction tx = null;
Session session = sessionFactory.getCurrentSession();
try {
tx = session.beginTransaction();
// do DB stuff.
tx.commit(); // or, sometimes session.getTransaction().commit();
} catch (Exception e) {
if (tx != null) {
tx.rollback();
}
throw new CustomDbException(e);
}
In some cases, when closing the session, we do session.getTransaction().commit() at a minimum, this is incosistent, but I'm not sure if it's giving a different trasancation or otherwise causing some problems.
We've been seeing intermittent issues with LockAcquisitionException: could not execute statement, StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect), and TransactionException: nested transactions not supported. We're not trying to do nested exceptiosn and always clean up the transaction, but I'm starting to think that maybe the sessions is being shared.
The application is multi threaded, and I'm starting to suspect that getCurrentSession is actually being shread across threads. I was under the impression that by setting hibernate.current_session_context_class to thread, then getCurrentSession() would provide a separate session per thread. Should I be taking a different approach here? Should I be using openSession() instead, or somehow configuring hibernate to give me unique sessions per thread?
We use #JmsListener methods, and the transactional exceptions seem most prevalent there, but are not localized there.
Exact hibernate versions are as follows:
hibernate: [ 'org.hibernate.common:hibernate-commons-annotations:4.0.4.Final',
'org.hibernate:hibernate-core:4.3.11.Final',
'org.hibernate:hibernate-hikaricp:4.3.11.Final'],
hikari: 'com.zaxxer:HikariCP:2.4.1',

How to bootstrap weld-osgi version 2 in SE application

It's really not funny. There is no information in internet how to run weld-osgi second version (2.1.2.final) in se app. Instructions for ver 1 don't work.
Let the developers be ashamed that they didn't provide necessary samples. I wrote them here.
So, I have and OSGi activator and I want to get beans from it. In GF4 I used this:
private BeanManager getBeanManager() throws NamingException
{
try{
InitialContext initialContext = new InitialContext();
return (BeanManager) initialContext.lookup("java:comp/BeanManager");
}
catch (NamingException e) {
System.out.println("Couldn't get BeanManager through JNDI");
return null;
}
}
But in SE application I can't get it through JNDI.
Also I tried:
Weld weld=new Weld();
BeanManager beanManager=weld.getBeanManager();
But at the second line I get
Caused by: java.lang.IllegalStateException: Singleton is not set. Is
your Thread.currentThread().getContextClassLoader() set correctly?
How can I use CDI starting from activator? What is my mistake?
EDIT:
What I did - I found two source code of two programs that use it, but it's really no so easy to write on their base (at least for me). The first is here and the second is here
The weld-osgi subproject is not supported anymore with Weld 2. Instead, integration with OSGi is provided using the Pax CDI project.
Pax CDI documentation can be found here: https://ops4j1.jira.com/wiki/display/PAXCDI/Pax+CDI
Additional information can be found at:
- http://karaf.apache.org/manual/latest/users-guide/cdi.html
- https://github.com/weld/core/blob/master/examples/osgi/README.md

jdbc connection - socket connection

A few days ago my website crashed and showed me this error:
java.lang.NoClassDefFoundError: Could
not initialize class
com.omicc.hibernate.util.HibernateUtil
So I asked the hosting company about any changes that they may have made. They fixed the problem and told me to use JDBC connections instead of socket connections.
I am using hibernate and c3p0 with MySQL and as far as I know they use JDBC connections.
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
So do any of you guys know what he was talking about? :D (and yes he is not answering now!)
EDITED>>>>
Solved!, so here is what i did
i upgraded my hibernate from hibernate from 3.5.0 to 3.6.1
and new hibernate required hibernate-jpa-2.0-api-1.0.0.Final.jar and slf4j-simple1.6.1 .
and problem solved.
i think that the hosting company updated their hibernate.jar and it caused some reference problems.
Rewrite your HibernateUtil so it doesn't instantiate in a static block. Instead make it a singleton with a synchronized getInstance. Then
private static SessionFactory cache;
synchronized SessionFactory getInstance() throws SQLException {
if (cache != null) return cache;
// try/catch and rethrow SQLException
try {
Class.forName("com.mysql.jdbc");
} Exception (e) {
throw new SQLException(e);
}
// Test connection with JDBC
// Create a non connection pooled raw connection, try/finally close it
// throw SQL Exception if it fails
testMe()
// finally create the sessionFactory
.... build your Configuration object
.... then
try {
SessionFactory me = ....buildSessionFactory
} catch (RuntimeException e) {
throw new SQLException(e);
}
cache = me;
return cache;
}
Some comments: some people will prefer an unchecked exception, which is fine.
The reason I like doing the raw connection once is that on startup it tends to bollix up connection pool/hibernate less if the SQL Server happens to be done. Once they initialize successfully I've not had recovery issues. But that's a personal taste thing, and you could skip testMe() as well.
Point is this way you will SEE the Exception occurring, and I predict to you it will clearly implicate the connection to the hosting company :)

Categories