I have 2 methods:
public static Ticket issueTicket(User user,Service service,String[] seats) {
Session ticSess= DB.factory.openSession();
ticSess.beginTransaction();
Date d= new Date();
Ticket ticket=new Ticket(d, service, user);
ticSess.save(ticket);
ticSess.getTransaction().commit();
int seatCount=seats.length;
for (int i=0;i<seatCount;i++){
int seatID=Integer.parseInt(seats[i]);
Seat seat=getSeatByID(seatID);
seat.setTicket(ticket);
ticSess.update(seat);
}
return ticket;
}
and,
public static Seat getSeatByID(int seatID) {
Session proSess = DB.factory.openSession();
proSess.beginTransaction();
Seat c = (Seat) (proSess.load(Seat.class, seatID));
proSess.getTransaction().commit();
return c;
}
when I call issueTicket method I get:
illegally attempted to associate a proxy with two open Sessions
and If I close the session in getSeatByID method there will be another error telling that the session is closed. Here is the Stack Trace:
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:164)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:285)
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185)
at ir.ac.shirazu.cse.Terminal.Seat_$$_javassist_9.setTicket(Seat_$$_javassist_9.java)
at ir.ac.shirazu.cse.Database.DB.issueTicket(DB.java:231)
Try closing proSess in getSeatByID() before returning. Currently the Seat indeed remains attached to session opened in getSeatByID().
I got same problem . But after using singleton pattern for session i'm done. I'm using Hibernate 4.2.x.
This is my session class is used to get sessions for DB transactions etc.
public class SessionClass {
static Session session = PoolManager.getSession();
public static Session getSession() {
if (session != null || session.isOpen()) {
return session;
} else {
session = PoolManager.getSession();
return session;
}
}
}
Hibernate Helper Class I'm using.
public class PoolManager {
private static final SessionFactory sessionFactory;
private static final ServiceRegistry serviceRegistry;
static {
try {
// Create the SessionFactory from standard (hibernate.cfg.xml)
// config file.
Configuration configuration = new Configuration();
configuration.configure();
serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
} catch (Throwable ex) {
// Log the exception.
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static Session getSession() {
return sessionFactory.openSession();
}
}
I ran into this issue when trying to associate a entity from a Envers Session.
Fixed that by "refreshing" said entity (retrieving it on my non-Envers session via PK fetch) before bubbling it up to my algorithm.
use session.opensession().get(.....).. instead of session.opensession().load(.....)
what if you do a proSess.evict(c) before committing proSess?
Related
Recently I upgrade the weblogic server from 11g to 12.2.1.3 and redeploy the web application. When run the application, it throws below exception. It is something wrong in session. I tried to google in the web but not luck as it is creating session problem. I believe no problem in hiberate config or mapping xml file as I tried according to the google search (e.g. https://stackoverflow.com/questions/12010056/org-hibernate-invalidmappingexceptioncould-not-parse-mapping-document-from-reso) but still same problem.
%%%% Error Creating SessionFactory %%%%
org.hibernate.InvalidMappingException: Could not parse mapping document from resource com/xxxx/hibernate/SSmsPromotion.hbm.xml
at org.hibernate.cfg.Configuration.addResource(Configuration.java:588)
at org.hibernate.cfg.Configuration.parseMappingElement(Configuration.java:1606)
at org.hibernate.cfg.Configuration.parseSessionFactory(Configuration.java:1574)
at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:1553)
at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:1527)
at org.hibernate.cfg.Configuration.configure(Configuration.java:1447)
at com.xxxx.hibernate.HibernateSessionFactory.rebuildSessionFactory(HibernateSessionFactory.java:69)
at com.xxxx.hibernate.HibernateSessionFactory.getSession(HibernateSessionFactory.java:53)
at com.xxxx.onlineapplications.manager.SBranchManager.getSBranchCatList(SBranchManager.java:19)
public class SBranchManager{
...........
public ArrayList getSBranchCatList(String langId, String appType) throws Exception{
ArrayList branchCatList = new ArrayList();
Session session = HibernateSessionFactory.getSession(); <--- Line 19
................
}
}
public class HibernateSessionFactory {
private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";
private static final ThreadLocal threadLocal = new ThreadLocal();
private static Configuration configuration = new Configuration();
private static org.hibernate.SessionFactory sessionFactory;
private static String configFile = CONFIG_FILE_LOCATION;
public static Session getSession() throws HibernateException {
Session session = (Session) threadLocal.get();
if (session == null || !session.isOpen()) {
if (sessionFactory == null) {
rebuildSessionFactory(); <---- Line 53
}
session = (sessionFactory != null) ? sessionFactory.openSession()
: null;
threadLocal.set(session);
}
return session;
}
public static void rebuildSessionFactory() {
try {
configuration.configure(configFile); <--- Line 69
sessionFactory = configuration.buildSessionFactory();
} catch (Exception e) {
System.err
.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
}
}
}
It is solved by removing the below line in weblogic.xml
<!-- <container-descriptor>
<prefer-web-inf-classes>true</prefer-web-inf-classes>
</container-descriptor> -->
There's an example from the web on how to use annotations in Hibernate (before that I've worked on the same example, but it used .xml instead. And I've managed to make it work without exceptions).
So now I have:
Initial session factory creation failedjava.lang.NoSuchFieldError: namingStrategy
Exception in thread "main" java.lang.ExceptionInInitializerError
at firstproject.HibernateUtil.<clinit>(HibernateUtil.java:14)
at firstproject.StudentDAO.addSubject(StudentDAO.java:82)
at firstproject.Test.main(Test.java:12) Caused by: java.lang.NoSuchFieldError: namingStrategy
at org.hibernate.cfg.AnnotationConfiguration.reset(AnnotationConfiguration.java:250)
at org.hibernate.cfg.Configuration.<init>(Configuration.java:125)
at org.hibernate.cfg.Configuration.<init>(Configuration.java:119)
at org.hibernate.cfg.AnnotationConfiguration.<init>(AnnotationConfiguration.java:108)
at firstproject.HibernateUtil.<clinit>(HibernateUtil.java:11)
... 2 more
Here is some code, that may help:
public class HibernateUtil {
private static final SessionFactory sessionFactory;
static {
try {
sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory(); // HibernateUtil.java:11
} catch (Throwable ex) {
System.err.println("Initial session factory creation failed" + ex);
throw new ExceptionInInitializerError(ex); // HibernateUtil.java:14
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
public class StudentDAO {
public Long addSubject(Subject subject) {
Session session = HibernateUtil.getSessionFactory().getCurrentSession(); // StudentDAO.java:82
session.beginTransaction();
Long result = (Long) session.save(subject);
session.getTransaction().commit();
return result;
}
}
public class Test {
public static void main(String[] args) {
StudentDAO dao = new StudentDAO();
Subject subject = new Subject();
subject.setSubjectName("Mathematics");
dao.addSubject(subject); // Test.java:12
}
}
Hi Kleeo
You have written the following line in HibernateUtil class.
sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
Replace this line of code with the below written line & retry. I hope this will work for you.
sessionFactory = new Configuration().configure().buildSessionFactory();
AnnotationConfiguration has been Deprecated in Hibernate 3.6.
As you can see in the documentation (see link below) all functionality has been moved to Configuration.
You can use safely Configuration instead.
sessionFactory = new Configuration().configure().buildSessionFactory();
AnnotationConfiguration documentation:
http://docs.jboss.org/hibernate/core/3.6/javadocs/org/hibernate/cfg/AnnotationConfiguration.html
Use below :
sessionFactory = new Configuration().configure().buildSessionFactory();
And also ensure that your cfg.xml should be present in root of src folder. Else you will get exception of unable to find cfg file
I am trying to fetch data from table I am using following code to fetch data from db.
public List<UserInfoSetting> fetchAll(Long aid) {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
Transaction tx = session.beginTransaction();
List<UserInfoSetting> obj = null;
try {
String hql = "select s from UserInfoSetting s where s.atom.id=:aid ";
Query query = session.createQuery(hql);
query.setParameter("aid", aid);
obj = query.list();
tx.commit();
} catch (HibernateException e) {
if (tx != null) {
tx.rollback();
}
} finally {
session.close();
}
return obj;
}
HibernateUtil.java
public class HibernateUtil {
private static final SessionFactory sessionFactory;
static {
try {
sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
It is showing following exception
root cause
java.lang.NoClassDefFoundError: Could not initialize class business.HibernateUtil
setting.user.UserCommunicationDao.fetchAll(UserCommunicationDao.java:146)
setting.user.UserCommunication.fetchAll(UserCommunication.java:64)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:483)
How to resolve the above problem
This means either you haven't got all the right Hibernate libraries in your class path, or you're not including the classes you've written. If you're coding using Eclipse, find the project settings and add the Hibernate libraries as dependencies for the project.
You will need to add hibernate-core, but quite a few others too.
Maven would help...
And it would help you a lot if you changed the name of your HibernateUtil class: there is a standard Hibernate class with the same name. Although in principle you can have two classes with the same name but in different packages, it'll be likely to cause confusion. (For instance, it's not entirely clear which one it can't find.)
due to the frequently insert event , (it's a chat room program)
it's always occurs "exception : java heap outOfMemory...."
and i think that it's cause from here
here is my correct code
public static boolean saveMethod(String userid,String username,String msg){
Configuration cfg = new Configuration();
cfg.configure(); //here is correct
SessionFactory factory = cfg.buildSessionFactory();
Session session = factory.openSession();
Transaction tx = null;
tx = session.beginTransaction();
Transaction transaction = null;
try{
....jump
transaction = session.beginTransaction();
session.save(saveMsg);
transaction.commit();
return true;
}catch(Exception e){
return false;
}
}
so i change the method to that
Configuration cfg = new Configuration();
cfg.configure();// error here
SessionFactory factory = cfg.buildSessionFactory();
Session session = factory.openSession();
Transaction tx = null;
tx = session.beginTransaction();
Transaction transaction = null;
public static boolean setPublicMsg(String userid,String username,String msg){
//insert
}
Syntax error on token "configure", Identifier expected after this
token
how can i write here ?
or anyone have some idea about the "exception : java heap outOfMemory...." in hibernate?
i'm try to change the tomcat setting, but it's not working
thanks !
Just by looking at your saveMethod(), it looks like you are creating configuration and sessionFactory per each save call. You can simply avoid this.
When your application starts, you can build the sessionFactory once and reuse as much as you need.
For example, you can use a HibernateUtil class to get the sessionFactory as below.
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static SessionFactory sessionFactory;
public static SessionFactory getSessionFactory() {
if (sessionFactory == null ) {
sessionFactory = new Configuration().configure().buildSessionFactory();
}
return sessionFactory;
}
}
Then in your saveMethod() you get the sessionFactory as below.
public static boolean saveMethod(String userid,String username,String msg){
SessionFactory factory = HibernateUtil.getSessionFactory();
// ...
}
Context
I'm creating a database environment where I'd like to split data in several different schemas to be used for different groups of users. Although, one of these databases should be shared to everyone due to it contains common entities.
Suppose databases:
DB1 - Common entities;
Wheels entity
DB2 - Group "A";
Cars entity
DB3 - Group "B";
Motorcycles entity
I have three different projects:
Project 1:
Wheels bean
Project 2:
Cars constructor
Project 3:
Motorcycles constructor
Problem
I'm trying to access wheels (Project 1) from projects/schemas (2,"A") and (3,"B")
First question: Is it possible?
Second: How can I do it?
hibernate.cfg.xml in project 2 is configured to
<property name="hibernate.connection.url">jdbc:mysql://99.999.999.99:3306/DB2</property>
This necessarily must restrict all the connections to DB2, or there's another way to add a new connection or work with all databases in 3306 port, or at least DB1?
Mapping the entities from project1 in project 2 seems not to be succeeded too, like:
<mapping class="com.company.project1.Wheels"
package="com.company.project1.Wheels" resource="com/company/project1/Wheels.hbm.xml"/>
Configuration
Eclipse Indigo
MySql 5.5
Hibernate 3.0 (mapping through xml instead annotations)
Win 7
Thanks for helping!
You can use #Table(catalog="") to specify database to which they belong to and then also can make relation across database.
in your case Wheel maps to DB1, Car to DB2 and MotorCycle to DB3 using catalog attribute.
i have used this solution with MySQL and MSSQL and works perfectly fine. only constraint this has all three DB has to be in same database server and user which is being used to access db should have appropriate permission to all DB.
As this solution just adds schema name against table in all queries.
I would divide my project in multiple self sustained projects. The Wheel project will be self sufficient project which takes care of Wheel entity.
Project 1: Wheel
This project will define Hibernate entities and DAO to access / modify wheel definitions.
Also I would configure a separate datasource in this project which points to DB1.
Entity classes:
#Entity
public class Wheel {
}
DAO classes:
#Repository
public class WheelDAO {
#Persistence
private EntityManager em;
}
Basically the idea is to separate application at DAO level. And manage transactions at Service level. Imaging WheelDAO (wired to DB1 datasource) and CarDAO (wired to DB2 datasource) and inject these in CarService.
DB1 DB2 DB2
| | |
WheelDAO CarDAO MotorcycleDAO
\_____________/ |
\_____|__________________________/
| |
| |
CarService MotorCycleService
I suggest to use Spring as IOC container to manage these dependency. Although you can achieve this without using Spring too.
What you need is just a db connection factory which allows you to use db that you want when you need it.
Take a look at the class below which you can adapte to resolve your issue
import java.net.URL;
import java.util.HashMap;
import javax.security.auth.login.Configuration;
public class HibernateUtil {
private static Log log = LogFactory.getLog(HibernateUtil.class);
private static HashMap<String, SessionFactory> sessionFactoryMap = new HashMap<String, SessionFactory>();
public static final ThreadLocal sessionMapsThreadLocal = new ThreadLocal();
public static Session currentSession(String key) throws HibernateException {
HashMap<String, Session> sessionMaps = (HashMap<String, Session>) sessionMapsThreadLocal.get();
if(sessionMaps == null) {
sessionMaps = new HashMap();
sessionMapsThreadLocal.set(sessionMaps);
}
// Open a new Session, if this Thread has none yet
Session s = (Session) sessionMaps.get(key);
if(s == null) {
s = ((SessionFactory) sessionFactoryMap.get(key)).openSession();
sessionMaps.put(key, s);
}
return s;
}
public static Session currentSession() throws HibernateException {
return currentSession("");
}
public static void closeSessions() throws HibernateException {
HashMap<String, Session> sessionMaps = (HashMap<String, Session>) sessionMapsThreadLocal.get();
sessionMapsThreadLocal.set(null);
if(sessionMaps != null) {
for(Session session : sessionMaps.values()) {
if(session.isOpen())
session.close();
}
;
}
}
public static void closeSession() {
HashMap<String, Session> sessionMaps = (HashMap<String, Session>) sessionMapsThreadLocal.get();
sessionMapsThreadLocal.set(null);
if(sessionMaps != null) {
Session session = sessionMaps.get("");
if(session != null && session.isOpen())
session.close();
}
}
public static void buildSessionFactories(HashMap<String, String> configs) {
try {
// Create the SessionFactory
for(String key : configs.keySet()) {
URL url = HibernateUtil.class.getResource(configs.get(key));
SessionFactory sessionFactory = new Configuration().configure(url).buildSessionFactory();
sessionFactoryMap.put(key, sessionFactory);
}
} catch(Exception ex) {
ex.printStackTrace(System.out);
log.error("Initial SessionFactory creation failed.", ex);
throw new ExceptionInInitializerError(ex);
} // end of the try - catch block
}
public static void buildSessionFactory(String key, String path) {
try {
// Create the SessionFactory
URL url = HibernateUtil.class.getResource(path);
SessionFactory sessionFactory = new Configuration().configure(url).buildSessionFactory();
sessionFactoryMap.put(key, sessionFactory);
} catch(Throwable ex) {
log.error("Initial SessionFactory creation failed.", ex);
throw new ExceptionInInitializerError(ex);
} // end of the try - catch block
}
public static void closeSession(String key) {
HashMap<String, Session> sessionMaps = (HashMap<String, Session>) sessionMapsThreadLocal.get();
if(sessionMaps != null) {
Session session = sessionMaps.get(key);
if(session != null && session.isOpen())
session.close();
}
}
} // end of the class
http://www.java-forums.org/