Mantis Bugtracker
  

Viewing Issue Simple Details Jump to Notes ] View Advanced ] Issue History ] Print ]
ID Category Severity Reproducibility Date Submitted Last Update
0000904 [Resin] minor always 01-31-06 08:26 03-27-06 14:18
Reporter ferg View Status public  
Assigned To ferg
Priority normal Resolution fixed  
Status closed   Product Version 3.0.17
Summary 0000904: CMP updates not visible in selects
Description (rep by Steven Grimm)

We have a session bean that calls an entity bean to perform some
updates, then does a JDBC call that joins with the entity bean's table.
Something like

    fooBean.setName("Joe");
    stmt = connection.prepareStatement("select f.name from foo f, bar b
where f.id = b.foo_id");

What seems to be happening is that the "foo" table is not getting
updated by the call to setName(). Most likely the container is just
deferring the update until the end of the transaction for performance
reasons. At least, that's what WebLogic does. They provide a "defer
updates until end of transaction" option that can be set to false in
cases like the above.

What, if anything, is the equivalent in Resin? How do I get updates to
entity beans to show up in JDBC queries within the same transaction?

I thought maybe the "distributed" option to <ejb-server> would help, as
documented on http://www.caucho.com/resin-3.0/cmp/ejb-server.xtp [^] -- but
when I try to include <distributed> in my resin.conf's <ejb-server>, I
get an XML validation error that claims there's no such thing as a
<distributed> tag! What's the story with that?

Additional Information
Attached Files

- Relationships

- Notes
(0000895)
ferg
02-23-06 10:39

Since the problem of CMP updates not showing up in JDBC queries in the
same transaction is our last real stumbling block to deploying Resin,
I've been digging a little deeper into it. The previously offered advice
of calling EntityManager.flush() didn't work, but it seemed like it
should have, so that's where I've been focusing.

The problem seems to be that when I call

  EntityManager mgr = (EntityManager)new
InitialContext().lookup("java:comp/EntityManager");
  mgr.flush();

the flush() call is getting a different AmberConnectionImpl than the CMP
code is. Specifically, EntityManagerImpl.getAmberConnection() calls
AmberManager.createAmberConnection(). That creates a new
AmberConnectionImpl(), which of course doesn't have any of the pending
changes from earlier in the transaction.

In other words, the flush() is flushing the wrong cache of updates to
the CMP entities.

I *think* that EntityManagerImpl.getAmberConnection() should first be
trying to get the AmberConnectionImpl associated with the currently open
transaction, if any.

Does that seem right? I will start trying to figure out how to do that.
 
(0000896)
koreth
02-23-06 18:03

Patch for this problem, more robust than what I sent to the mailing list (but still needs improvement for actual release since it hardwires a JNDI name):

--- modules/resin/src/com/caucho/amber/ejb3/EntityManagerImpl.java- 2006-02-
23 11:30:07.808570253 -0800
+++ modules/resin/src/com/caucho/amber/ejb3/EntityManagerImpl.java 2006-02-
23 17:52:12.444163560 -0800
@@ -41,10 +41,15 @@
 import com.caucho.amber.query.AbstractQuery;

 import com.caucho.ejb.EJBExceptionWrapper;
+import com.caucho.ejb.EjbServerManager;
+import com.caucho.ejb.xa.EjbTransactionManager;
+import com.caucho.ejb.xa.TransactionContext;

 import com.caucho.jca.UserTransactionProxy;
 import com.caucho.jca.CloseResource;

+import com.caucho.naming.*;
+
 import com.caucho.util.L10N;

 /**
@@ -57,6 +62,8 @@

   private AmberManager _amberManager;

+ private EjbTransactionManager _transactionManager;
+
   private boolean _isRegistered;
   private AmberConnectionImpl _aConn;

@@ -67,6 +74,15 @@
   {
     _amberManager = amberManager;
     _entityManagerProxy = proxy;
+
+ // Look up the transaction manager so we can get transactional Amber
+ // connections.
+ EjbServerManager serverManager = (EjbServerManager)
+ Jndi.lookup("java:comp/env/cmp/resin-ejb-server");
+ if (serverManager != null)
+ _transactionManager = serverManager.getTransactionManager();
+ else
+ _transactionManager = null;
   }

   /**
@@ -235,6 +251,12 @@
    */
   private AmberConnectionImpl getAmberConnection()
   {
+ if (_transactionManager != null) {
+ TransactionContext context = _transactionManager.getTransactionContext();
+ if (context != null)
+ return context.getAmberConnection();
+ }
+
     if (_aConn == null) {
       /*
       if (_depth == 0)
 
(0000923)
koreth
03-08-06 16:44

I should add that my patch is to fix the problem of the explicit EntityManager.flush() not working. My patch does *not* fix the underlying bug (CMP updates are invisible to subsequent JDBC queries in the same transaction).
 
(0000951)
ferg
03-27-06 14:18

ejb/0al5

With 3.0.19, the CMP context is associated with the Amber/persistence context/EntityManager at java:comp/env/persistence/PersistenceContext/resin-ejb.

You can use that EntityManager to flush the current dirty entities.
 

- Issue History
Date Modified Username Field Change
01-31-06 08:26 ferg New Issue
01-31-06 10:04 koreth Issue Monitored: koreth
02-23-06 10:39 ferg Note Added: 0000895
02-23-06 18:03 koreth Note Added: 0000896
03-08-06 16:44 koreth Note Added: 0000923
03-27-06 14:18 ferg Note Added: 0000951
03-27-06 14:18 ferg Assigned To  => ferg
03-27-06 14:18 ferg Status new => closed
03-27-06 14:18 ferg Resolution open => fixed
03-27-06 14:18 ferg Fixed in Version  => 3.0.19


Mantis 1.0.0rc3[^]
Copyright © 2000 - 2005 Mantis Group
36 total queries executed.
29 unique queries executed.
Powered by Mantis Bugtracker