My requirement is, I have two db instances in db2 with same db schema. We take backup of db every year. So we have db like dbinstance_2014, dbinstance_2015 and dbinstance_2016.
My application is working on 2016 instance. I need to create report year wise in that case I need to use older instances. I have create two methods to create session factory. One method will create current years dbinstance connection and other will dynamically create connection to older db.
Current year sessionFactory is used throughout the application. In case of report generation I am trying to use another method which creates sessionfactory dynamically.
But I am getting exception:
org.hibernate.HibernateException: No CurrentSessionContext configured
How can I resolve this error?
Related
Is it possible to choose Mapper to execute in Mybatis?
I am using dynamically routed datasource and give it as parameter to sqlSessionFactory - it is working.
The problem is, however, that different databases may require other SQL queries (very small differences, but differences).
Is it possible to create dynamically routed sqlSessionFactory - and give to them other package mappers?
This is how you obtain a session factory:
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
A couple of things are declared in in mybatis-config.xml, amongst whom are the datasources and the mappers.
Then create another Mybatis config file (with its own datesource and mappers) and dynamically choose the file to build the session factory. You can still provide the connection when opening the session, although I recommend using the implicit one provided by the factory because it will match with the mapper. (Unless this is a complex application where you need to reuse the connection, e.g: to complete a transaction)
I've got a couple of class instance variables: userSF which is a SessionFactory and userCfg which is a Configuration set up to use user.cfg.xml. When I have someone log into my application their database login information is grabbed from a file the following happens:
userCfg.setProperty("hibernate.connection.username", username);
userCfg.setProperty("hibernate.connection.password", password);
userSF = userCfg.buildSessionFactory();
When the user logs out of the application it closes the session factory. then when another user tries to log in that same code is called with username and password changing based on who is logging in. The problem is that the second time it's called I'm getting an exception:
org.hibernate.HibernateException: HHH000469: The ClassLoaderService can not be reused. This instance was stopped already.
Is there a way to reuse the SessionFactory variable for multiple logins?
You should not create a SessionFactory for each logged in user / configuration. It is a very costly component and should target the Singleton pattern. Use a single instance per context within your application.
If you have multiple configurations you can cache multiple instances in application scope. Depending on your application this maybe a static Singleton class using a Map<MyUserPasswordKey, SessionFactory> or in an JAVA-EE container a #ApplicationScoped EJB or JSF-Bean.
In case a context based on a user-password key will lead to too many SessionFactory instances you maybe should change your application to either manage them in permission groups or restrict your functionality within your data access or service layer.
We have an application which uses multiple databases to store the same data for different countries.
For example a Subscription object might be associated with Germany or Spain. If it's a German subscription, it needs to be stored in a different database to the Spanish subscriptions. The databases are identical in structure, but they have different contents.
We are running on jboss 5, and have a different datasource config (*ds.xml) file for each one, generated dynamically at startup. They are stored in JNDI - so we have DataSourceDE, DataSourceES, etc.
Here's how it should work: if a request comes in saying 'fetch subscription 17 for Germany' then I calculate that the datasource should be DataSourceDE and use JPA / hibernate to go fetch that object from the correct database. There will be a subscription 17 in the Spanish database too, which I don't want in this example.
I can generate the persistence.xml automatically to create the extra persistence units for the datasources, but the Subscription class is annotated with the following:
#PersistenceContext(unitName="core")
This is not going to work - how can I set the persistence context on the java object dynamically?
What you are trying to achieve is known as Multi-Tenancy. Here is a perfectly suitable tutorial for your question to make it work.
The main idea is to use a Stateless session bean which has a reference to both persistence units. Depending on what has to be done, this bean does a lookup to call the corresponding EntityManager. Furthermore here:
Multi-Tenancy With EJB 3.1 and JPA 2.0
You can change the persistence context for the EntityManager at runtime like this:
EntityManagerFactory emf =
Persistence.createEntityManagerFactory(persistenceUnitName);
EntityManager em = emf.createEntityManager();
If I load a City object from DB using Hibernate session, and then using the same session which has not been used for an hour, if I do a city.getCountry() which should lazy load the Country object, I get an Exception (Connection marked as broken because of SQLSTATE(08003)). I got two general questions:
Is lazy loading just another new JDBC connection and totally
independent connection under the hood?
What kind of parameters in hibernate connection pool configuration I
need to tune to increase the timeout for these kind of situations?
I'm not using transactions.
I'm using HikariCP and my DB is Postgrsql.
In a CMT J2EE environement (Container Managed Transaction) what transaction / connection is used when I JDNI-lookup for a DataSource object and invoke DataSource.getConnection?
Is this connection part of the (potentially distributed) transaction? Does getConnection() return the same Connection every time I call it for the same DataSource object? I only know using Connections by the same EntityManager using native SQL statements.
It is something that keeps me puzzling. As I understood the SessionContext defines a transactional system that is used throught every time I use a datasource. I have the problem that inside a session bean a DataSource.getConnection() is used and this connection is then closed. If a problem is encountered SessionContext.setForRollBack(true) is issued.
Therefore how does the transactional context of a service relate to a DataSource?
If we spawn a new Connection each time a datasource is used or at least looked up, I have problems to understand things I already know. Any clarification would be wonderful. I know container managed transaction and other systems, but the actual behavior of DataSource is totally beyond me.
In Java EE a transaction is a concept that is not exclusive to databases, for example JMS connection sessions can also be part of container managed transaction. The idea is if one or more than one method is running under container managed transaction boundary, the container will commit or rollback the transaction as needed.
In data base related data source, there are multiple layers, fist is the managed pool of connection which is maintained by the container, second is the actual connection management of the database driver with the database, in Java a Connection is an abstraction for a session with a database and not a physical connection, that is managed by the driver.
With the above context, your questions could be addressed viz.:
what transaction / connection is used when I JDNI-lookup for a DataSource object and invoke DataSource.getConnection.
Under container managed transaction, though it is implementation dependent, a connection/session with the database is associated that is marked with the transaction boundary. The actual physical connection could be shared with the database by the driver but that is transparent to application as well as the container.
Is this connection part of the (potentially distributed) transaction? Does getConnection return the same Connection every time I call it for the same DataSource object?
Refer above, a Connection has no relation with the underlying socket to the database as opened by the driver. It is logically a separate session and if within transaction boundary, the same session is associated with the connection retrieved from the data source, how this is implemented is part of the container design
I have the problem that inside a session bean a DataSource.getConnection is used and this connection is then closed
In a pooled implementation for connection a Connection.close() has no impact, the connection is returned to the pool(http://commons.apache.org/proper/commons-dbcp/api-1.3/org/apache/commons/dbcp/PoolableConnection.html), this behaviour is similar for all pools. So clsing a connection does not necessarily disassociate it from container transaction boundary, though a connection should not be closed within container managed transaction. Similarly, commit, setAutoCommit, rollback must not be called from within CMT as this will issue the following command equivalent to the actual database and the behaviour of the transaction after that will undefined.
Have a look at the declaration of the #Resource annotation.
It includes a shareable attribute that allows you to specify connection sharing behaviour. It defaults to true, which means that you will get connection sharing automatically if you do nothing.
This attribute is also included in the XML schema for any resource-ref defined datasources that you may lookup using JNDI.
All resources (JDBC, JMS, ResourceManager) that are included during an invocation are enrolled in the current transaction. You may sometimes need to specify the use of XA for this to work correctly.