How to remove Entity Bean in CMP stateless session bean in EJB 3.0

Posted on 2009-05-04
Last Modified: 2013-12-11
EJB 3.0 is new to us. We just started to migrate our EJB2.1 to EJB3.0. We are having issues. Can anyone help?

The table has a unique index#2 besides the primary key.
The following transaction (in a single themod) works great in container managed session bean in EJB 2.1:
1. find theEntity using theValue of theColumn for index#2;
2. if( theEntity exists ) then delete theEntity;
3. insert newEntity with new primary key but the same theValue of theColumn for index#2.

The method is translated in an EJB 3.0 like below:
private EntityManager em is global in the session bean and is injected in PersistenceContext;
annotation TransactionAttribute(REQUIRED) for the method;
namedQuery.getResultList() in 1. (Couldn't use getSingleResult since sometimes it returns none);
em.remove( theEntity ) in 2.;
em.persist( newEntity ) in 3..

The first time calling this method, no problem. The newEntity gets inserted. The second time, we get DuplicateKeyException; If we add em.flush() in step 2 after the em.remove( theEntity ), we get OptimisticLockException.

What's wrong with this translation? Or what else I have to do in order for this translation to work? Thanks!!!
Question by:leowwx
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 3

Author Comment

ID: 24304694
Any one?

Expert Comment

ID: 24314051
How do you instantiate 'newEntity'? With a constructor, or do you reuse 'theEntity' with modified properties? If the latter, try to persist an entirely new object, instead of reusing a previously removed entity...

Author Comment

ID: 24315473
Thanks for the comments.
I used a constructor for the 'newEntity'.

I did a lot experiments on this. And finally I got something. It seems the way to retrieve 'theEntity' matters. If I use 'namedQuery.getResultList()', it seems it always put a lock on the row. So I changed to use a local Entity Manager to get anEntity by theValue of theColumn for index#2, then use construntor to new a EntityPK pk, then set this pk values from the pk of 'anEntity', then call the global em's find method to get 'theEntity' by this new pk. This way, the DuplicateKeyException is gone, in fact, I got no errors from the console, but the row in database was not replaced.

So, I am stuck here. Don't know if I need to try Bean Managed Persistent and manually commit.
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!


Author Comment

ID: 24316540
After I inserted some system.out.println statements and I think I got the reason now.

We have micro seconds in the primary key column of the table. The ejb3.0 jpa maps java.util.Date to timestamp in the primary key of the table, which looses precision when the query returns theEntity by the values of the columns in the index#2. When em.remove(theEntity) gets excuted, em woundn't find the row to delete.


Expert Comment

ID: 24317636
Yes, timestamps can be tricky sometimes :-)

I'm glad that you have found the cause. In the future, you can always let the JPA implementation print out the SQL statements executed in the logs for diagnosting. Like that, you can 'see' what's happening under the hood.

Author Comment

ID: 24318305
Which may mean that we can't use EJB3.0 because we have many tables in db2 that have micro second port in the Timestamp type column in primary keys. Just read ejb3.0 specification and only java.util.Date and java.sql.Date can be in primary key of an entity. I think they both precision in millisecond.

Thanks any way.

Accepted Solution

Mr_It earned 500 total points
ID: 24323259
The spec is what all JPA providers have to follow, but most implementations are less strict and have additional features.

I just tested with TIMESTAMP as a PK in Oracle and java.sql.Timestamp in the entity, and it seems to work. I use Hibernate as a JPA implementation.
public class MyEntity implements Serializable {
    private Timestamp id = new Timestamp(System.nanoTime());
    public Timestamp getId() {
    public void setId(Timestamp id) { = id;

Open in new window


Author Comment

ID: 24328133
Yeah. I reread the specification and it implys using other types in the primary key may work and it only makes the entity bean not portable. That's not a problem for us. So I tried using primary key in my entity too and it worked in our websphere - db2 environment. So, we are continue the migration now. Thanks for your comments. One thing that worth mention is that the em.flush() is needed for my transaction in between the remove of theEntity and persist the newEntity. Thanks again.

Featured Post

Moving data to the cloud? Find out if you’re ready

Before moving to the cloud, it is important to carefully define your db needs, plan for the migration & understand prod. environment. This wp explains how to define what you need from a cloud provider, plan for the migration & what putting a cloud solution into practice entails.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This exercise is about for the following scenario: Dmgr and One node with 2 application server. Each application server contains it owns application. Application server name as follows server1 contains app1 server2 contains app1 Prereq…
Upgrading Tomcat – There are a couple of methods to upgrade Tomcat is to use The Apache Installer is to download and unzip and run the services.bat remove|install Tomcat6 Because of the App that we are working with, we can only use Tomcat 6.…
The viewer will learn how to implement Singleton Design Pattern in Java.
This tutorial covers a practical example of lazy loading technique and early loading technique in a Singleton Design Pattern.
Suggested Courses

635 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question