EJB, EntityManager and merging problems

  • Thread starter Przemek M. Zawada
  • Start date
P

Przemek M. Zawada

Hello,

I've been looking for nice database I/O way and I've decided to use
(suggested by NetBeans) the EJB.

In fact, I was looking for something, which would speed up my work,
unfortunately I'm stuck for last 4 hours with annoying update database
problem.

Fetching data from database works perfectly. BUT, when I'm trying to
update records, I no changes are made in the database. I wish you'll
help me finding the reason.

As it has been described in many, many google-found pages, I've build an
object, which I use as entity manager. Sample:

@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class UserManager {

@PersistenceContext(unitName="MyDbPU")
private EntityManager em;
@Resource
SessionContext context;
@EJB
private CupUserFacade userFacade; // Dunno whether it's required?

public int UpdateUser() {
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("MyDbPU");

em = emf.createEntityManager();
CupUser user = (CupUser) em.find(CupUser.class, 2);
user.setName("fonk you");
try {
CupUser upUser = em.merge(user);
System.err.println(upUser.getName());
em.close();

return 1;
} catch (Exception ex) {
System.err.println(
"UserManager.UpdateUser(): "
+ ex.getMessage());
return 0;

}
}

@PersistenceContext
public void setEntityManager(EntityManager eman) {
this.em = eman;
}
}

The log file sayz:

FINEST: Execute query ReadObjectQuery(referenceClass=CupUser sql="SELECT
.... FROM cup_user WHERE (ID = ?)")
SEVERE: fonk you
FINEST: Merge clone with references entity.CupUser[id=2]
SEVERE: true // is open() EntityManager
FINER: release unit of work

In fact it does not say anything about updating queries...
That's annoying, because I really don't know what am I doing wrong.

Please help. Thank you very much.

Przemek M. Zawada
 
A

Arved Sandstrom

Przemek said:
Hello,

I've been looking for nice database I/O way and I've decided to use
(suggested by NetBeans) the EJB.

In fact, I was looking for something, which would speed up my work,
unfortunately I'm stuck for last 4 hours with annoying update database
problem.

Fetching data from database works perfectly. BUT, when I'm trying to
update records, I no changes are made in the database. I wish you'll
help me finding the reason.

As it has been described in many, many google-found pages, I've build an
object, which I use as entity manager. Sample:

@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class UserManager {

@PersistenceContext(unitName="MyDbPU")
private EntityManager em;
@Resource
SessionContext context;
@EJB
private CupUserFacade userFacade; // Dunno whether it's required?

public int UpdateUser() {
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("MyDbPU");

em = emf.createEntityManager();
CupUser user = (CupUser) em.find(CupUser.class, 2);
user.setName("fonk you");
try {
CupUser upUser = em.merge(user);
System.err.println(upUser.getName());
em.close();

return 1;
} catch (Exception ex) {
System.err.println(
"UserManager.UpdateUser(): "
+ ex.getMessage());
return 0;

}
}

@PersistenceContext
public void setEntityManager(EntityManager eman) {
this.em = eman;
}
}

The log file sayz:

FINEST: Execute query ReadObjectQuery(referenceClass=CupUser sql="SELECT
... FROM cup_user WHERE (ID = ?)")
SEVERE: fonk you
FINEST: Merge clone with references entity.CupUser[id=2]
SEVERE: true // is open() EntityManager
FINER: release unit of work

In fact it does not say anything about updating queries...
That's annoying, because I really don't know what am I doing wrong.

Please help. Thank you very much.

Przemek M. Zawada

Hi, Przemek

You've got a bit too much going on here at one. For starters, decide
whether you are going to use @PersistenceUnit *or* @PersistenceContext
*or* Persistence.createEntityManagerFactory().createEntityManager() to
obtain your entity managers. Container-managed will be one of the first
2 choices; application-managed is the third.

I strongly recommend reading
http://download.oracle.com/javaee/6/tutorial/doc/bnbqw.html.

As an aside, note that inside a transactional boundary em.find() will
returned a managed entity - there is no need to then merge it. Again, I
recommend that you read the above link; however, depending on your
scenario either the container will take care of transactions for you
(with container-managed EMs), or you will, by either using the
EntityTransaction or UserTransaction APIs. In this case you had an
application-managed EM but no transaction...hence no update.

AHS
 
P

pmz

Przemek said:
I've been looking for nice database I/O way and I've decided to use
(suggested by NetBeans) the EJB.
In fact, I was looking for something, which would speed up my work,
unfortunately I'm stuck for last 4 hours with annoying update database
problem.
Fetching data from database works perfectly. BUT, when I'm trying to
update records, I no changes are made in the database. I wish you'll
help me finding the reason.
As it has been described in many, many google-found pages, I've build an
object, which I use as entity manager. Sample:
@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class UserManager {
    @PersistenceContext(unitName="MyDbPU")
    private EntityManager em;
    @Resource
    SessionContext context;
    @EJB
    private CupUserFacade userFacade; // Dunno whether it's required?
    public int UpdateUser() {
        EntityManagerFactory emf =        
        Persistence.createEntityManagerFactory("MyDbPU");
        em = emf.createEntityManager();
        CupUser user = (CupUser) em.find(CupUser.class, 2);
    user.setName("fonk you");
        try {
            CupUser upUser = em.merge(user);
            System.err.println(upUser.getName());
            em.close();
            return 1;
        } catch (Exception ex) {
            System.err.println(
        "UserManager.UpdateUser():  "
            + ex.getMessage());
            return 0;
        }
    }
    @PersistenceContext
    public void setEntityManager(EntityManager eman) {
        this.em = eman;
    }
}
The log file sayz:
FINEST: Execute query ReadObjectQuery(referenceClass=CupUser sql="SELECT
... FROM cup_user WHERE (ID = ?)")
SEVERE: fonk you
FINEST: Merge clone with references entity.CupUser[id=2]
SEVERE: true // is open() EntityManager
FINER: release unit of work
In fact it does not say anything about updating queries...
That's annoying, because I really don't know what am I doing wrong.
Please help. Thank you very much.
Przemek M. Zawada

Hi, Przemek

You've got a bit too much going on here at one. For starters, decide
whether you are going to use @PersistenceUnit *or* @PersistenceContext
*or* Persistence.createEntityManagerFactory().createEntityManager() to
obtain your entity managers. Container-managed will be one of the first
2 choices; application-managed is the third.

I strongly recommend readinghttp://download.oracle.com/javaee/6/tutorial/doc/bnbqw.html.

As an aside, note that inside a transactional boundary em.find() will
returned a managed entity - there is no need to then merge it. Again, I
recommend that you read the above link; however, depending on your
scenario either the container will take care of transactions for you
(with container-managed EMs), or you will, by either using the
EntityTransaction or UserTransaction APIs. In this case you had an
application-managed EM but no transaction...hence no update.

AHS

Thank you for your time! Yeah, I've discovered that I've mixed all of
everything, very stupid. I've been instructed to try such solution:

@Stateless
public class UserManager {
....
@PersistenceContext(unitName = "RallySuitePU")
private EntityManager em;
....
void Update() {
System.err.println("em.find() start");
CupUser user = (CupUser) em.find(CupUser.class, 2); /// Crashed here
with NullPointerException, of course
user.setUserType(User_Type);
user.setUserName("New Username Here");
System.err.println("UpdateUser.END");
}

Obviously my em is NullPointer - why it has not been initialized? Or
how should I do it?

All the best,
Przemek M. Zawada
 
P

pmz

Przemek said:
Hello,
I've been looking for nice database I/O way and I've decided to use
(suggested by NetBeans) the EJB.
In fact, I was looking for something, which would speed up my work,
unfortunately I'm stuck for last 4 hours with annoying update database
problem.
Fetching data from database works perfectly. BUT, when I'm trying to
update records, I no changes are made in the database. I wish you'll
help me finding the reason.
As it has been described in many, many google-found pages, I've build an
object, which I use as entity manager. Sample:
@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class UserManager {
    @PersistenceContext(unitName="MyDbPU")
    private EntityManager em;
    @Resource
    SessionContext context;
    @EJB
    private CupUserFacade userFacade; // Dunno whether it's required?
    public int UpdateUser() {
        EntityManagerFactory emf =        
        Persistence.createEntityManagerFactory("MyDbPU");
        em = emf.createEntityManager();
        CupUser user = (CupUser) em.find(CupUser.class, 2);
    user.setName("fonk you");
        try {
            CupUser upUser = em.merge(user);
            System.err.println(upUser.getName());
            em.close();
            return 1;
        } catch (Exception ex) {
            System.err.println(
        "UserManager.UpdateUser():  "
            + ex.getMessage());
            return 0;
        }
    }
    @PersistenceContext
    public void setEntityManager(EntityManager eman) {
        this.em = eman;
    }
}
The log file sayz:
FINEST: Execute query ReadObjectQuery(referenceClass=CupUser sql="SELECT
... FROM cup_user WHERE (ID = ?)")
SEVERE: fonk you
FINEST: Merge clone with references entity.CupUser[id=2]
SEVERE: true // is open() EntityManager
FINER: release unit of work
In fact it does not say anything about updating queries...
That's annoying, because I really don't know what am I doing wrong.
Please help. Thank you very much.
Przemek M. Zawada
Hi, Przemek
You've got a bit too much going on here at one. For starters, decide
whether you are going to use @PersistenceUnit *or* @PersistenceContext
*or* Persistence.createEntityManagerFactory().createEntityManager() to
obtain your entity managers. Container-managed will be one of the first
2 choices; application-managed is the third.
I strongly recommend readinghttp://download.oracle.com/javaee/6/tutorial/doc/bnbqw.html.
As an aside, note that inside a transactional boundary em.find() will
returned a managed entity - there is no need to then merge it. Again, I
recommend that you read the above link; however, depending on your
scenario either the container will take care of transactions for you
(with container-managed EMs), or you will, by either using the
EntityTransaction or UserTransaction APIs. In this case you had an
application-managed EM but no transaction...hence no update.

Thank you for your time! Yeah, I've discovered that I've mixed all of
everything, very stupid. I've been instructed to try such solution:

@Stateless
public class UserManager {
...
@PersistenceContext(unitName = "RallySuitePU")
private EntityManager em;
...
void Update() {
  System.err.println("em.find() start");
  CupUser user = (CupUser) em.find(CupUser.class, 2); /// Crashed here
with NullPointerException, of course
  user.setUserType(User_Type);
  user.setUserName("New Username Here");
  System.err.println("UpdateUser.END");

}

Obviously my em is NullPointer - why it has not been initialized? Or
how should I do it?

All the best,
Przemek M. Zawada

Okay, I've managed where the problem is. I'm not sure whether it's
allowed to do (what I've done) in servlet part, but for tests I've
allowed myself to do it.

I've add in the servlet elements:
@PersistenceContext(unitName = "RallySuitePU")
private EntityManager em;

@Resource
UserTransaction ut;

and in the doPost section, I've made such test:

ut.begin();
CupUser u = (CupUser) em.find(CupUser.class,
Integer.parseInt(request.getParameter("userId")));
u.setUserEmail("fonkyou!");
em.merge(u);
ut.commit();

The row has been updated (in the database), with such log message:

FINER: TX binding to tx mgr, status=STATUS_ACTIVE
FINEST: Execute query ReadObjectQuery(referenceClass=CupUser
sql="SELECT ID, IsActive, User_IsLocked, User_Contact, User_Mobile,
User_Password, User_Name, User_ReminderCode, User_Email,
User_FullName, User_LastLogin, User_Type FROM cup_user WHERE (ID
= ?)")
FINER: TX beforeCompletion callback, status=STATUS_ACTIVE
FINER: begin unit of work commit
FINER: TX afterCompletion callback, status=COMMITTED
FINER: end unit of work commit
FINER: release unit of work
FINER: client released

Unfortunately, I have some problems with data preview - in the browse
page I have the old data (e-mail value is i.e. old_value) but when I
view it as another page (edit-mode), the e-mail value is valid, new
one "fonkyou". About what I'm missing? Any refresh/reload/etc.
methods?

All the best,
Przemek M. Zawada
 
L

Lew

Trim your posts. Don't quote sigs.
ut.begin();
CupUser u = (CupUser) em.find(CupUser.class,
Integer.parseInt(request.getParameter("userId")));
u.setUserEmail("fonkyou!");
em.merge(u);

You ignored Arved's advice that this 'merge()' is unnecessary, I see.
ut.commit();

The row has been updated (in the database), with such log message:
...

Unfortunately, I have some problems with data preview - in the browse
page I have the old data (e-mail value is i.e. old_value) but when I

Apparently you didn't refresh the view.
view it as another page (edit-mode), the e-mail value is valid, new
one "fonkyou". About what I'm missing? Any refresh/reload/etc.
methods?

Yeah, the browser "submit" should cause the server to regen the page with the
updated values.
 
A

Arved Sandstrom

pmz said:
Pardon me.


Apparently I've tried not using the 'merge()', but no effect found!
[ SNIP ]

Don't get the idea that I'm saying that merge() is useless; just be
aware of specifically what it's for. It's for bringing detached entities
back into a persistence context; inside a transaction (and in this case
you've got a JTA transaction using the UserTransaction API) a find() or
query will return managed entities and so merge() is not required.

Also, if you use merge(), bear in mind that you must then use the
managed copy which is returned. You're not in the wrong here (except for
using merge in the first place); just keep this in mind. It's not a bad
habit to get into to always assign the return value from merge().

If you're doing this in a servlet bear in mind that entity managers are
not thread-safe, so I'd inject with @PersistenceUnit instead, to get an
EntityManagerFactory. Then create your EM from the EMF after you start
the user transaction.

AHS
 
P

pmz

....
If you're doing this in a servlet bear in mind that entity managers are
not thread-safe, so I'd inject with @PersistenceUnit instead, to get an
EntityManagerFactory. Then create your EM from the EMF after you start
the user transaction.

AHS

Thank you very much! I'll try to work your way, which I believe is the
good one ;)

All the best,
Przemek M. Zawada
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,070
Latest member
BiogenixGummies

Latest Threads

Top