Solved

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

Posted on 2009-05-04
8
809 Views
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!!!
0
Comment
Question by:leowwx
  • 5
  • 3
8 Comments
 

Author Comment

by:leowwx
ID: 24304694
Any one?
0
 
LVL 4

Expert Comment

by:Mr_It
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...
0
 

Author Comment

by:leowwx
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.
0
Space-Age Communications Transitions to DevOps

ViaSat, a global provider of satellite and wireless communications, securely connects businesses, governments, and organizations to the Internet. Learn how ViaSat’s Network Solutions Engineer, drove the transition from a traditional network support to a DevOps-centric model.

 

Author Comment

by:leowwx
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.

0
 
LVL 4

Expert Comment

by:Mr_It
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.
0
 

Author Comment

by:leowwx
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.
0
 
LVL 4

Accepted Solution

by:
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());
 
    ...
 
    @Id
    public Timestamp getId() {
	return this.id;
    }
 
    public void setId(Timestamp id) {
	this.id = id;
    }
 
    ...
}

Open in new window

0
 

Author Comment

by:leowwx
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.
0

Featured Post

Active Directory Webinar

We all know we need to protect and secure our privileges, but where to start? Join Experts Exchange and ManageEngine on Tuesday, April 11, 2017 10:00 AM PDT to learn how to track and secure privileged users in Active Directory.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Tools or ways to handle development of complex web applications 4 133
array11 challenge 16 72
mockito example issue 8 82
tomcat startup error 5 106
Configure Web Service (server application) I. Configure security for Web Services methods First, we need to protect Session bean which implements the service: 1. Open EJB deployment descriptor (ejb-jar.xml) in the EJB project that contains you…
There are numerous questions about how to setup an IBM HTTP Server to be administered from WebSphere Application Server administrative console. I do hope this article will wrap things up and become a reference for this task. You need three things…
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.

821 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