How do you create 2 persistent sessions and pointing at 2 different rdbms's

This relates to the PersistenceManager and the Sessions.
So have the orm code all going on one db. But would like to run same api generated against 2 db’s (say one mysql and the other oracle, or say a HSQLDB and Mysql) at the same time (can generate code for rdbms 1 and then mapping files for rdbms 2 fine). This is for one program that connects to 2 db’s (say oracle and ms sql), where both “connections” are against the same model/api. The orm can generate the hibernate config files, so I would assume it would be a matter of telling PersistenceManager which file to use when request a PersistentSession. BUT, as there is no API doc (Is there any org.orm api doc ? that would really help), how do you create 2 persistent sessions and pointing at 2 different rdbms’s (for the same API).

Hello alanww35,

Thank you for your message. We are sorry that currently we do not support running 2 persistence session pointing to different database at the same time (since our Persistent Manager is in singleton). May I know why you would like to do this?

Currently we do not have the Javadoc available for the orm.jar, but you can find the source at
http://files3.visual-paradigm.com/Resources/ORM/orm_src.zip

Best regards,
Rain Wong

okay, first thanks for the code. I can put a few fixes in. Is their an email to send them ?

Why do I want it. Migration scripts between 2 rdbms ? How about a mainly readonly config system, where I want a HSQLDB as an in memory readonly proxy, so if the db connection goes down, the system runs the readonly proxy until it can be reconnected ? API between both db’s is the same, and Hyperion manages the DB stuff. Just need to be able to connect to 2 db’s. NOTE - this works because of LOW rate of updates, but it will work perfectly for our needs.

Also, need to have the option to specify per session (ie. multi-thread app). At the moment the doc (help file) says save, delete etc for POJO are on the Session, but they are actually on the persistent manger base class. The doc is GOOD design, but something has been lost in imp.

What I have done is extend all my DAOImp’s with a _AbstractDAOImp that has a getSession() and set Session(). Also modified the DAOFactoryImp that if a session is set, it will create a new (not cached xxxDAOImp) and set the session using the abstract class. In each xxxDAOImp, instead of calling xxxPersistenceManager.getInstance().getSession() i call this.getSession(), and put some smarts in the this.getSession() ie. if set, return the session set , else THEN call the singleton.

BUT , its those calls to SAVE on the persistence manager that is breaking things. Will extend persistencManage with a save where I can specifiy the session to use.

NOTE - see you help files, you put the save, delete etc on the session in chapter16, but on the manager in the imp. Bug ?

Hello alanww35,

Thanks for replying. Actually the default session type should be working fine in multi-thread environment. You mention “need to have the option to specify per session (ie. multi-thread app)”, do you mean you experienced problems in using the ORM in multi-thread environment?

And according to your description, you would like to set session to dao factory and dao. May I know why you would like to do this?

Best regards,
Rain Wong

sure. In multi-thread env, there is that setting (off the top of my head can’t remember it) that creates a session instance per call to getInstance. Looking at the code, for PersistenceManager.saveObject say, it sees if the sesson is a user session ? in which case it creates some code for auto-commit. What I am experiencing is a loss of control over the transaction boundary, especially when I mix DAO control with HQL queries. I haven’t had the time to look in the code, but given the lack of doco on the ORM stuff it was had to work out. But tieing all the DAO code to a singleton is just bad. It hard codes threaded behaviour. In my particular case, all my SQL updates are sent to queue and as a set of tasks which are then worked on by a thread from a worker queue. So basically I create a POOL of sessions. In general, dump the singleton, or give the users an option in the factories to override it. For your generated code, you can still easily support the embedded singleton pattern, but you can also let users manage session as they see fit. In my case, this would also allow me to easily (1 line of code say) create 2 session to 2 databases, and easily use the dao’s. For such a small change, you get a whole level of functionality. You can’t help but win. ie. give the users the option to use the singleton. Its great for simple stuff or stand alone apps, but I actually use the ORM code in our own “server”. I will send some examples on the small change I did, but it gives my DAO’s the full flexability. Creating a persistent session is also not the best. Look at the saveObject() code that the DAO’s call (again, your doc say in chapter 16 it should call the persistent session, as that is also the owner of any current transactions), they call PersistentManager. saveObject (save for delete). I made it call SaveOrUpdate on the session. So i maintain the contract with the session and its contract in turn with any associated transactions. Its about also maintaining and not blurring the lines for seperation of concerns.

Here is what I did

---------8<--------------


public abstract class DAOFactory {
	private static DAOFactory _factory = new DAOFactoryImpl();

	public static DAOFactory getDAOFactory() {
		return _factory;
	}

// New Method ->
	public static DAOFactory getDAOFactory(PersistentSession p_Session)
	{
		return new DAOFactoryImpl(p_Session);
	}


---------8<--------------



public class DAOFactoryImpl extends DAOFactory
{

// new member variable -->

	private PersistentSession m_Session = null;

...


	public xxxDAO getxxxDAO()
	{
		xxxDAO l_Result = _xxxDAO;

		if (null != m_Session)
		{
			l_Result = new xxxDAOImpl();
		}

// _AbstractDAOImp and _setPersistentSession method are My class  that all DAO extend.	
((_AbstractDAOImpl)l_Result)._setPersistentSession(m_Session);

		return l_Result;

	}

---------8<--------------

in xxx.dao.impl package ->


public abstract class _AbstractDAOImpl
{
	private PersistentSession m_Session = null;

	protected PersistentSession _getPersistentSession() throws PersistentException
	{
		PersistentSession l_Result = m_Session;

		if (null == m_Session)
		{
			l_Result = com.missingmatter.config.orm.ConfigManagementServicePersistentManager.instance().getSession();
		}

		return l_Result;

	}


	public void _setPersistentSession(PersistentSession p_Session)
	{
		m_Session = p_Session;
	}

}


and then


public class xxxDAOImpl extends _AbstractDAOImpl implements xxxDAO
{

...

eg.

public XXX listXXXByQuery(String condition, String orderBy) throws PersistentException
	{
		PersistentSession session = _getPersistentSession();
		return listxxxByQuery(session, condition, orderBy);
	}


So the above keeps the API for the DAO’s the same, but with a very simple change allows full control in my code on how i want to USE the dao’s. I can mix DAO’s and hql queries in a multi-thread app and keep transaction boundaries.

By default the original behaviour is maintained. But I can easily change it.

Also don’t mix calls to persistent manager and persistent session in the DAO’s. Break’s the design assumptions for the pattern.

Why limit a great tool when for say 1 days work you can make it so much better.

if you look at the “iterateXXXByQuery” static method on each DAO, you will see 2 signatures. One that specifies an Session and the other using the singleton. Its partial solution to the problem I was having. If you could do something along the lines I have done, that would be consistent then for the whole API, not just 1 method call, and would help the unify the DAO and Query object with regard to transaction management, especially in a multi-threaded app.