Hi,
I am currently trying to use hibernate (without spring) on my server in order to store contract in my database.
Unfortunately, i have an issue with collection and session : (it seems to be a very common error, but I didn't find any soltuion concerning mine)
org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions
Here is my HibernateSession factory :
Code:
public class HibernateSessionFactory {
private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";
private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
private static Configuration configuration = new Configuration();
private static org.hibernate.SessionFactory sessionFactory;
private static String configFile = CONFIG_FILE_LOCATION;
static {
try {
configuration.configure(configFile);
sessionFactory = configuration.buildSessionFactory();
} catch (Exception e) {
System.err
.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
}
}
private HibernateSessionFactory() {
}
public static Session getSession() throws HibernateException {
Session session = (Session) threadLocal.get();
if (session == null || !session.isOpen()) {
if (sessionFactory == null) {
rebuildSessionFactory();
}
session = (sessionFactory != null) ? sessionFactory.openSession()
: null;
threadLocal.set(session);
}
return session;
}
public static void rebuildSessionFactory() {
try {
configuration.configure(configFile);
sessionFactory = configuration.buildSessionFactory();
} catch (Exception e) {
System.err
.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
}
}
public static void closeSession() throws HibernateException {
Session session = (Session) threadLocal.get();
threadLocal.set(null);
if (session != null) {
session.close();
}
}
public static org.hibernate.SessionFactory getSessionFactory() {
return sessionFactory;
}
public static void setConfigFile(String configFile) {
HibernateSessionFactory.configFile = configFile;
sessionFactory = null;
}
public static Configuration getConfiguration() {
return configuration;
}
}
and my hibernate.cfg.xml :
Code:
<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">xxxxx</property>
<property name="hibernate.connection.url">jdbc:mysql://10.83.69.182:3307/rda_bdd2</property>
<property name="hibernate.connection.username">administrator</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<mapping resource=/Mapping/Installment.hbm.xml" />
<mapping resource="/Mapping/Contract.hbm.xml" />
</session-factory>
</hibernate-configuration>
Here is an example of my dao :
Code:
public class ContractHome extends BaseHibernateDAO{
private static final Log log = LogFactory.getLog(ContractHome.class);
public void save(Contract transientInstance) {
log.debug("save Contract instance");
try {
Transaction tx = getSession().beginTransaction();
getSession().saveOrUpdate(transientInstance);
tx.commit();
getSession().close();
log.debug("save successful");
} catch (RuntimeException re) {
log.error("save failed", re);
throw re;
}
}
public List findAll()
{
log.debug("finding all contract instances");
try {
String queryString = "from Logica.FSI.RDA.Pojo.Contract";
Query queryObject = getSession().createQuery(queryString);
List list = queryObject.list();
return list;
} catch (RuntimeException re) {
log.error("find all failed", re);
throw re;
}
}
}
BaseHibernateDAO :
Code:
public Session getSession() {
return HibernateSessionFactory.getSession();
}
and last but not least : ManageList, in order to call the dao class :
Code:
public class ManageList{
private static ManageList instance;
private ArrayList<Contract> listContratBDD = new ArrayList<Contract>() ;
private Date lastEditContract ;
private ContractHome cDao ;
private ManageList(){
lastEditContract = new Date();
lastEditPerson = new Date();
cDao = new ContractHome();
}
public static ManageList getInstance() {
if (instance == null) {
instance = new ManageList();
}
return instance;
}
public void loadContractFromDatabase()
{
this.listContratBDD = (ArrayList<Contract>)cDao.findAll();
}
public void saveContractToDatabase(ArrayList<Contract> list){
for (Contract c : list) {
cDao.save(c);
}
}
public ArrayList<Contract> getListContratDatabase() {
return listContratBDD;
}
public void setListContratBDD(ArrayList<Contract> listContratBDD) {
this.listContratBDD = listContratBDD;
}
}
Now you have all data you need (i think) to understand my problem or to solve yours if i can put a "resolved" in the topic :)
When I am using the manageListclass in my main class, everything work fine. I can take the contract list from the database, and save it also.
Code:
public static void main(String[] args) throws Exception {
System.out.println("Loading list");
ManageList ML = ManageList.getInstance();
ML.loadContractFromDatabase();
System.out.println("Loading list success");
new Server();
System.out.println("Server ready...");
while(true) Thread.sleep(1);
}
The problem is that I am using a webservice. My a .NET client consume the webservice and call the manageList : saveContractToDatabase(ArrayList<Contract> list), I receive this mistake :
"Illegal attempt to associate a collection with two open sessions"
If someone can give me a hint to solve this. Thank in advance
Best regards,
Vlado