Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

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

Posted on 2009-05-04
8
Medium Priority
?
817 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
[X]
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
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
Application Discovery Service in AWS

In the era of the cloud, customers migrating away from their existing on-premise infrastructure. This requires lots of planning, strategies, and effort to identify their existing resources and determine how best to migrate.  Datacenter migrations happen in four phases -

 

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 2000 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

On Demand Webinar - Networking for the Cloud Era

This webinar discusses:
-Common barriers companies experience when moving to the cloud
-How SD-WAN changes the way we look at networks
-Best practices customers should employ moving forward with cloud migration
-What happens behind the scenes of SteelConnect’s one-click button

Question has a verified solution.

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

Most of the developers using Tomcat find it easy to configure the datasource in Server.xml and use the JNDI name in the code to get the connection.  So the default connection pool using DBCP (or any other framework) is made available and the life go…
A solution for Fortify Path Manipulation.
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.

664 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