You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@openjpa.apache.org by chintan4181 <ch...@gmail.com> on 2011/06/13 18:53:25 UTC

How to find entity belong which EntityManger?

Hello All

In our project we are using JPA2.0 with two persistence units. I have two
persistence manager and able to initialize successfully on IBM WAS. I am
using RSA 8.0 to generate the entities. we have two database one is SQL
server and another on is DB2. My requirement is before calling persist
method on EntityManager i have first choose the EntityManager in other words
how to make sure that Entity/Table belongs to SQLServer or DB2 below API's
are returning false

@PersistenceContext(unitName="MIApplicationSQL")
private EntityManager emSqlServer; 

@PersistenceContext(unitName="MIApplicationDB2")
private EntityManager emDB2;

private EntityManager getEntityManager(FwrkDO fnDO) {

EntityManager em = null; 

// emSqlServer is an EntityManager for SQL server
// emDB2 is an EntityManager for Db2
//fndo is an entity which need to be validated 

Set&lt;EntityType&lt;?&gt;> entities = emDB2.getMetamodel().getEntities();
Set&lt;EntityType&lt;?&gt;> entities2 =
emSqlServer.getMetamodel().getEntities();

// contains method returns false 
if (entities2.contains(fnDO)) {
em = emSqlServer;
} else if (entities.contains(fnDO)) {
em = emDB2;
} 

// EntityManager.contains also returning false
if (emSqlServer.contains(fnDO)) {
em = emSqlServer;
} else if (emDB2.contains(fnDO)) {
em = emDB2;
}
return em;
}

How to ensure the entity/table is belongs to SQLServer or DB2 server.
 


--
View this message in context: http://openjpa.208410.n2.nabble.com/How-to-find-entity-belong-which-EntityManger-tp6470903p6470903.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.

Re: How to find entity belong which EntityManger?

Posted by Pinaki Poddar <pp...@apache.org>.
Hi,
> do you know why it is happening?
Do not know enough on how or where you are using this double-em solution to
comment. 
A sanity check of this sort might help

Metamodel m1 = emDB2.getMetamodel();
Metamodel m2 = emSS.getMetamodel();
assertNotSame(m1, m2);

Set&lt;EntityType&lt;?&gt;> types1 = m1.getEntities();
Set&lt;EntityType&lt;?&gt;> types2 = m2.getEntities();

// verify two sets are *either* dis-joint or at least their difference is
non-empty.

> so that we can achieve XA transaction?
The fact that 
a) your units are JTA 
and you are in a container environment, 
*should* make both the transactions from two ems join the 'global
transaction' managed by the container. 

If you do not see that is happening, see the facility EntityManager.join()
to join a transaction. 

-----
Pinaki 
--
View this message in context: http://openjpa.208410.n2.nabble.com/How-to-find-entity-belong-which-EntityManger-tp6470903p6479579.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.

Re: How to find entity belong which EntityManger?

Posted by chintan4181 <ch...@gmail.com>.
Hi Pinaki,

We tried the code you suggested. Now problem is, Entities are replicated in
both entity manager i.e. I can see DB2 entities list in SQL server entity
manager. do you know why it is happening?

Java code
######################################
/** 
	 * 
	 * <p>persistent context unit for SQLServer</p>
	 * 
	 * @generated "UML-to-EJB 3.0
(com.ibm.xtools.transform.uml2.ejb3.java.internal.UML2EJB3Transform)"
	 */
	@PersistenceContext(unitName="MIApplicationSQL")
	private EntityManager emSqlServer; 

	/** 
	 * 
	 * <p>DB2 entity manager</p>
	 * 
	 * @generated "UML-to-EJB 3.0
(com.ibm.xtools.transform.uml2.ejb3.java.internal.UML2EJB3Transform)"
	 */
	@PersistenceContext(unitName="MIApplicationDB2")
	private EntityManager emDB2;
###############################################
<persistence version="2.0"
	xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
	<persistence-unit name="MIApplicationSQL" transaction-type="JTA">
		<description>MIApplication Datasource</description>
		<jta-data-source>jdbc/MIApplicationSQL</jta-data-source>
		<class>com.jeeframework.persistence.Area</class> 
		<properties>
			<property name="openjpa.Log" value="SQL=TRACE,JDBC=TRACE" />
		</properties>
	</persistence-unit>
	<persistence-unit name="MIApplicationDB2" transaction-type="JTA">
		<description>MIApplication Datasource</description>
		<jta-data-source>jdbc/MIApplicationDB2</jta-data-source>
		<class>com.jeeframework.persistence.User</class> 
		<properties>
			<property name="openjpa.Log" value="SQL=TRACE,JDBC=TRACE" />
		</properties>
	</persistence-unit>
</persistence>

If we create two different persistent.xml (one for DB2 unit and other for
SQL server unit) then, can we make both entity manager as part of single
transaction so that we can achieve XA transaction?

thanks
chintan

--
View this message in context: http://openjpa.208410.n2.nabble.com/How-to-find-entity-belong-which-EntityManger-tp6470903p6479214.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.

Re: How to find entity belong which EntityManger?

Posted by ljnelson <lj...@gmail.com>.
On Mon, Jun 13, 2011 at 4:25 PM, Pinaki Poddar [via OpenJPA] <
ml-node+6471682-2008051213-155969@n2.nabble.com> wrote:

> A method like this may work (I am writing this in an email, so no
> warranty;)
>
> /**
>   * Affirms if the class of the given instance belongs to the given
> metamodel.
> **/
> boolean contains(Metamodel m, Object instance) {
>    Set<EntityType<?>> pTypes = m.getEntities();
>    for (EntityType<?> pType : pTypes) {
>         if (instance.getClass() == pType.getJavaType())
>               return true;
>    }
>    return false;
> }
>

...and I made the mistake of reading the original poster's problem code too
quickly and assumed that this (generally speaking) was what he was doing.
Obviously, as you pointed out, that is NOT what he was doing.

Thanks for the (second-order :-)) education.

Best,
Laird


--
View this message in context: http://openjpa.208410.n2.nabble.com/How-to-find-entity-belong-which-EntityManger-tp6470903p6471693.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.

Re: How to find entity belong which EntityManger?

Posted by Pinaki Poddar <pp...@apache.org>.
Hi,

   MetaModel is not static. Every persistence unit (i.e.
EntityManagerFactory) is associated with a MetaModel.

   My guess is you are referring to "static metamodel" as the canonical
metamodel classes generated at compile time. 

  These two, however, are very different concepts.   

Let us discuss the later first. Assume that you have @Entity classe P
defined in a persistent unit U1. 

When you compile P.java, you can activate annotation processing as follows:

$ javac -Aopenjpa.metamodel=true P.java 

This will activate an OpenJPA-specific Annotation Processor and that
processor will generate source code for P_.java which would be available
alongside P.java. P_.java will also be compiled to P_.class.

Class P_ is called static canonical metamodel for class P. 
'Static' because all variables in P_.java are static. Best is to take a look
at P_.java.

P_.class provides a means to write Criteria query that a Java compiler can
verify for correctness. A more detailed description and usage of Criteria
query can be found at [1].

If you are not using Criteria query, then these canonical metamodel classes
are irrelevant.


Now let us talk about metamodel per se. Every persistent unit has a
metamodel during runtime, irrespective of whether you have generated
'canonical metamodel classes' or not during compile time.

You obtain a reference to it as you have done in your code
emf.getMetamodel().

But then your interpretation of its content is incorrect.
-------------- your code ------------  
Set&lt;EntityType&lt;?&gt;> entities = emDB2.getMetamodel().getEntities();
Set&lt;EntityType&lt;?&gt;> entities2 =
emSqlServer.getMetamodel().getEntities();
   
// contains method returns false
if (entities2.contains(fnDO)) {
em = emSqlServer;
} else if (entities.contains(fnDO)) {
em = emDB2;
} 
--------------------------------------

The element of the set 'entities' or 'entities2' are EntityType (you may
think of them as persistent equivalent of java.lang.Class). 

'fnDO', on the other hand, is an instance of a persistent entity (if I have
guessed it right). No wonder that the entities.contains(fnDO) returns false.   

A method like this may work (I am writing this in an email, so no warranty;)

/**
  * Affirms if the class of the given instance belongs to the given
metamodel.
**/
boolean contains(Metamodel m, Object instance) {
   Set&lt;EntityType&lt;?&gt;> pTypes = m.getEntities();
   for (EntityType<?> pType : pTypes) {
        if (instance.getClass() == pType.getJavaType()) 
              return true;
   }
   return false;
}
  

-----
Pinaki 
--
View this message in context: http://openjpa.208410.n2.nabble.com/How-to-find-entity-belong-which-EntityManger-tp6470903p6471682.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.

Re: How to find entity belong which EntityManger?

Posted by ljnelson <lj...@gmail.com>.
On Mon, Jun 13, 2011 at 4:11 PM, Pinaki Poddar [via OpenJPA] <
ml-node+6471623-1303531452-155969@n2.nabble.com> wrote:

> May be a quick search for "metamodel" in OpenJPA documentation would have
> resolved it :)


Didn't intend the snub; my apologies.

I wonder why the OP's metamodel call fails?

L


--
View this message in context: http://openjpa.208410.n2.nabble.com/How-to-find-entity-belong-which-EntityManger-tp6470903p6471644.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.

Re: How to find entity belong which EntityManger?

Posted by Pinaki Poddar <pp...@apache.org>.
> I'm not that familiar with how (or if) OpenJPA does it.  

http://openjpa.apache.org/builds/latest/docs/manual/manual.html#d0e11235

> Both EclipseLink and Hibernate include options for automatically
> generating it.

So does OpenJPA.
May be a quick search for "metamodel" in OpenJPA documentation would have
resolved it :)

-----
Pinaki 
--
View this message in context: http://openjpa.208410.n2.nabble.com/How-to-find-entity-belong-which-EntityManger-tp6470903p6471623.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.

Re: How to find entity belong which EntityManger?

Posted by ljnelson <lj...@gmail.com>.
On Mon, Jun 13, 2011 at 2:53 PM, chintan4181 [via OpenJPA] <
ml-node+6471340-484087569-155969@n2.nabble.com> wrote:

> how do i check whether staticMetamodel created or not?
>

I'm not that familiar with how (or if) OpenJPA does it.  Both EclipseLink
and Hibernate include options for automatically generating it.

To see whether the static metamodel exists, check your build environment's
target area and look for classes that start with "_" and are named after
your entities.

Here is how Hibernate does it:
http://www.hibernate.org/subprojects/jpamodelgen.html  Note that this is
just a regular old annotation processor and has nothing to do with
Hibernate, so if OpenJPA does not offer the ability to statically generate
the metamodel you could do it with that.

Here is how EclipseLink does it (I think they just do it automatically):
http://wiki.eclipse.org/UserGuide/JPA/Using_the_Canonical_Model_Generator_%28ELUG%29

Best,
Laird


--
View this message in context: http://openjpa.208410.n2.nabble.com/How-to-find-entity-belong-which-EntityManger-tp6470903p6471457.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.

Re: How to find entity belong which EntityManger?

Posted by chintan4181 <ch...@gmail.com>.
how do i check whether staticMetamodel created or not?

--
View this message in context: http://openjpa.208410.n2.nabble.com/How-to-find-entity-belong-which-EntityManger-tp6470903p6471340.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.

Re: How to find entity belong which EntityManger?

Posted by ljnelson <lj...@gmail.com>.
On Mon, Jun 13, 2011 at 12:53 PM, chintan4181 [via OpenJPA] <
ml-node+6470903-1750357968-155969@n2.nabble.com> wrote:

> How to ensure the entity/table is belongs to SQLServer or DB2 server.
>

Perhaps your static metamodels were never created?  Your metamodel approach
is the one that I would try, myself.

Best,
Laird


--
View this message in context: http://openjpa.208410.n2.nabble.com/How-to-find-entity-belong-which-EntityManger-tp6470903p6471095.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.

Re: How to find entity belong which EntityManger?

Posted by Pinaki Poddar <pp...@apache.org>.
OpenJPA Slice addresses the same aspects that other providers address in
their own way (Hibernate calls it Shards, do not know about EclipseLink
equivalent). In future, JPA specification will standardize the behavior
against multiple databases. It is necessitated by the interest in
multi-tenancy as the applications move into cloud computing environment. 

Hence, your effort investment in Slice (or some of its equivalent) would not
go waste. 

The important architectural concern is two separate persistent contexts
(i.e. EntityManager instances em1 and em2) connected to two separate
database instances has a fundamental limitation. One of the core premise of
JPA is that a persistence context forms a 'group' (in a mathematical sense
of the word) i.e. the entities of em1 *can not* refer to entities in em2.
Whereas, when an application is connected to multiple databases, at some
point or other, a requirement will arise that would require instances from
different databases to refer to each other. At that point, a solution has to
be considered that can bring entities from multiple databases into the
*same* persistent context. Slice does that today, so does Hibernate Shards.

-----
Pinaki 
--
View this message in context: http://openjpa.208410.n2.nabble.com/How-to-find-entity-belong-which-EntityManger-tp6470903p6471780.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.

Re: How to find entity belong which EntityManger?

Posted by chintan4181 <ch...@gmail.com>.
Thanks Pinaki.

Since we are developing framework wrapper classes around JPA, is there a way
i can get this implemented in JPA itself so that i dont use any provider
specific classes. Because in future if someone wants to move to other JPA
Provider (i.e. HibernateJPA) then Slice might not work.



--
View this message in context: http://openjpa.208410.n2.nabble.com/How-to-find-entity-belong-which-EntityManger-tp6470903p6471077.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.

Re: How to find entity belong which EntityManger?

Posted by Pinaki Poddar <pp...@apache.org>.
You should take a look at Slice module of OpenJPA. It will simplify your
application against heterogeneous databases (i.e. DB2 ND SQLServer in your
case) . OpenJPA will manage/remember which database the entities comes from
or where should they be updated. The application controls where a new
instance be persisted (because OpenJPA, by itself, can not make that
decision:).

-----
Pinaki 
--
View this message in context: http://openjpa.208410.n2.nabble.com/How-to-find-entity-belong-which-EntityManger-tp6470903p6471039.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.