Solved

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

Posted on 2009-05-04
8
796 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
 

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
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
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

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Suggested Solutions

Introduction This article is the second of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers the basic installation and configuration of the test automation tools used by…
Introduction This article is the last of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers our test design approach and then goes through a simple test case example, how …
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.

705 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

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now