-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 22 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Is it ok to bind entity manager to the JNDI
PostPosted: Tue Jun 19, 2007 10:06 am 
Regular
Regular

Joined: Wed May 02, 2007 2:42 pm
Posts: 101
Hey,

I create factory by the Persistence class , create entity manager and than bind it to the JNDI.

In the DAO i look up to this EM and join to the transaction (without this it will not commit although that i add this attribute -
<property name="hibernate.transaction.factory_class" value="org.hibernate.ejb.transaction.JoinableCMTTransactionFactory"/>
to the persistence xml file )

Is this ok to bind the EM to the JNDI in the java code?

Thank you


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 19, 2007 10:10 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
No, this is not OK. The EntityManager is single-threaded and not thread-safe. You can not access the same EntityManager from two threads concurrently.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject: But you can have a parameter in the persistence.xml
PostPosted: Tue Jun 19, 2007 10:18 am 
Regular
Regular

Joined: Wed May 02, 2007 2:42 pm
Posts: 101
That bind the entity manager to the JNDI:
jboss.entity.manager.jndi.name

The issue that if i create the entity manager each time i call to the DAO i will not share the same persistence context.

if i call to DAO.save
and after it call to DAO.find

and in the DAO i create entity manager they will have the same persistence context and i will not find this record.

Thank you


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 20, 2007 2:25 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Quote:
That bind the entity manager to the JNDI:
jboss.entity.manager.jndi.name


That doesn't even exist.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 20, 2007 3:55 am 
Senior
Senior

Joined: Tue Jul 25, 2006 9:05 am
Posts: 163
Location: Stuttgart/Karlsruhe, Germany
It is documented here though:

http://docs.jboss.org/ejb3/app-server/reference/build/reference/en/html/entityconfig.htm

I am pretty certain it works in 4.0.4GA

Cheers,

Andy

_________________
Rules are only there to be broken


Top
 Profile  
 
 Post subject: The link is broken
PostPosted: Wed Jun 20, 2007 7:14 am 
Regular
Regular

Joined: Wed May 02, 2007 2:42 pm
Posts: 101
see this link:
http://docs.jboss.org/ejb3/app-server/r ... onfig.html

But i am not sure it is work.

Do you have an idea how to propograte (share) the persistence context (entity manager ) in the same thread.

I can use injection because i create this factory in run - time.

thank you


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 20, 2007 8:45 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Quote:
Do you have an idea how to propograte (share) the persistence context (entity manager ) in the same thread.


You propagate it along with the transaction context, by using EJB components that call each other. Your controller calls your DAOs inside the same transaction.

I need to investigate why the documentation says you can bind an EntityManager to JNDI. This is most likely a documentation glitch because it doesn't make any sense.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject: My DAO is not an ejb component
PostPosted: Wed Jun 20, 2007 10:24 am 
Regular
Regular

Joined: Wed May 02, 2007 2:42 pm
Posts: 101
Due to some restrictions (I need to create schema dynamically) I cant use injection , so I create the factory and bind it to the JNDI.

The issue that immediately after I save an Object I call to find but I get null although that the Object will save to the DB after the transaction will end (the transaction boundaries are in the stateless) .

In case that I use this code to find - em.find(Hotel.class, newHotel.getOrmID()); its okey in both cases , but I cant use this attitude because in the same transaction in another place I can call to another DAO and I want to see the Objects that I already saved .

As you see the persistence context is not propograte to the other DAO's or even to the same DAO if it call again.

I read all the new hibernate book i didnt find any explanation on how to use hibernate as a Jpa provider in a JTA enviroment without injection.

A lot of time you can use injection, like in case of using in a pojo classes.

Thank you.


DAO:

public class TestSimpleDao {

private EntityManager em = null;

public EntityManager getEntityManager(){
EntityManagerFactory emf = null;
try {
emf = (EntityManagerFactory) new InitialContext().lookup("java:/Demo");
} catch (NamingException e) {
e.printStackTrace();
}
em = emf.createEntityManager();
return em;
}

public Hotel saveHotel(Hotel newHotel) {
getEntityManager().persist(newHotel);
newHotel = getEntityManager().find(Hotel.class, newHotel.getOrmID());
return newHotel;
}
}


<persistence>
<persistence-unit name="Demo">
<jta-data-source>java:/DemoDS</jta-data-source>
<properties>
<property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.DefaultComponentSafeNamingStrategy" />
<property name="hibernate.transaction.factory_class" value="org.hibernate.ejb.transaction.JoinableCMTTransactionFactory"/>
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"/>
</properties>
</persistence-unit>
</persistence>

Hotel:

@Entity
@Table(name = "HOTELS")
public class Hotel implements Serializable {
@Id
@GeneratedValue(generator="system-uuid")
@GenericGenerator(name="system-uuid", strategy = "uuid")
@Column(name="managed_element_id")
protected String ormID = null;

private String name;
private String address;

@OneToMany(cascade=CascadeType.ALL)
@JoinColumn
private List<Room> rooms = new LinkedList<Room>();

private Hotel() {
}

public Hotel(String name, String address) {
this.name = name;
this.address = address;
}


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 20, 2007 10:37 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
I have no idea how this EM binding stuff in JNDI is supposed to work. Complain to Bill Burke (bill@jboss.org) and Carlo de Wolf (carlo.dewolf@jboss.com), who are responsible for it.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 20, 2007 10:40 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
And I'm not reading your code until you put it in code tags.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject: Thank you for your answer
PostPosted: Wed Jun 20, 2007 10:48 am 
Regular
Regular

Joined: Wed May 02, 2007 2:42 pm
Posts: 101
My code:

DAO :

Code:
public class TestSimpleDao {

   private EntityManager em = null;

    public EntityManager getEntityManager(){
       EntityManagerFactory emf = null;
      try {
         emf = (EntityManagerFactory) new InitialContext().lookup("java:/Demo");
      em = emf.createEntityManager();
      //em.joinTransaction();
      } catch (Exception e) {
         e.printStackTrace();
      }
       return em;
    }

   public Hotel saveHotel(Hotel newHotel) {
      try{
      getEntityManager().persist(newHotel);
      }catch(Exception e){
         e.printStackTrace();
      }
      //em.flush();
      //newHotel = getEntityManager().find(Hotel.class, newHotel.getOrmID());
      return newHotel;
   }



Code:
<persistence>
  <persistence-unit name="Demo">
    <jta-data-source>java:/DemoDS</jta-data-source>
    <properties>
      <property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.DefaultComponentSafeNamingStrategy" />
      <property name="hibernate.transaction.factory_class" value="org.hibernate.ejb.transaction.JoinableCMTTransactionFactory"/>
      <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"/>
    </properties>
  </persistence-unit>
</persistence>



Code:
@Entity
@Table(name = "HOTELS")
public class Hotel implements Serializable {
   @Id
    @GeneratedValue(generator="system-uuid")
    @GenericGenerator(name="system-uuid", strategy = "uuid")
    @Column(name="managed_element_id")
    public String ormID = null;

    private String name;
    private String address;

    @OneToMany(cascade=CascadeType.ALL)
    @JoinColumn
    private List<Room> rooms = new LinkedList<Room>();

    private Hotel() {
    }

    public Hotel(String name, String address) {
        this.name = name;
        this.address = address;
    }



    public String getOrmID() {
      return ormID;
   }


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 20, 2007 10:58 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
There are no transaction boundaries in your code, I have no idea what you want to actually do. You use two persistence contexts, one does a persist(), the other a find(). As long as the persist() isn't flushed and committed, the find() won't find it.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 20, 2007 11:29 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
So it turns out that this magic JBoss property is indeed doing something. What exactly is happening can only be a guess, contact Bill Burke if you like to know more. My guess:

@PersistenceContext(name="MyEntityManager") on a class (session bean) or method (in a session bean) would populate the naming context (ENC) of that bean with a container-managed and transaction-scoped EntityManager. You can look this up through the ENC with java:/comp/env/MyEntityManager as long as you obtain the ENC correctly. AFAIK that means you need to say new InitialContext() inside that beans code.

Now, what the JBoss magic property is doing is apparently binding a container-managed and transaction scoped EntityManager to the java:/ (or global) JNDI namespace. The only difference is that you can populate it with a configuration setting (no annotations on a class) and that you can look it up from anywhere. It's effectively a proxy that will scope itself to the transaction and propagate along with the transaction (usual rules).

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject: Thanks, i tried it and it didnt work corretly with multi
PostPosted: Wed Jun 20, 2007 12:38 pm 
Regular
Regular

Joined: Wed May 02, 2007 2:42 pm
Posts: 101
Threads.

I dont understand how they did this.

dont forget my DAO is simple class and this is not a good design that the DAO will need to be an Ejb component.

Can you think on solution on how to propograte the persistence context between all the DAO in the same thread.

is there an option to use somthing similar to current session in JPA?


Thank you.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 20, 2007 12:59 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Quote:
I dont understand how they did this.


Proxies.

Quote:
dont forget my DAO is simple class and this is not a good design that the DAO will need to be an Ejb component.


Who says that? This is nonsense, EJB components are plain Java classes. You don't even have to put an annotation on it.

Quote:
Can you think on solution on how to propograte the persistence context between all the DAO in the same thread.


Call your DAOs inside the same UserTransaction scope.

Quote:
is there an option to use somthing similar to current session in JPA?


This is _exactly_ what this magical JNDI binding is doing. Instead of sessionFactory.getCurrentSession() you say jndi.lookup("currentEntityManager") and it is magically the right persistence context (scoped and propagated with the transaction).

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 22 posts ]  Go to page 1, 2  Next

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
cron
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.