Olaf:
Many thanks for your help, and sorry this email will be quite long, with
the information you requested. I too had arrived at the conclusion that
the transaction management wasn't working by debugging using the
EclipseLink code.
Herewith my reasoning:
1. The fact that I am required to use an embedded database meant that I
need a JNDI DataSource so that EclipseLink and Spring Security can share
a database connection, since only one set of connections can be made at
a time.
2. Since I am using a JNDI DataSource and am without CMT (got too used
to EJBs, I think), the appropriate transaction manager in Spring (from
reading the documents) would be a DataSourceTransactionManager. The
relevant settings from my Spring setup:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<!-- setup for Spring MVC controllers et al. -->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBea
n">
<property name="dataSource" ref="dataSource"/>
<property name="loadTimeWeaver">
<bean
class="org.springframework.instrument.classloading.ReflectiveLoadTimeWea
ver"/>
</property>
</bean>
<bean
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPost
Processor"/>
<bean id="dataSource"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/satsDS"/>
</bean>
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
>
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:annotation-driven transaction-manager="txManager"/>
</beans>
(N.B. The definition of the DataSource from the Tomcat context is
probably working, since reading is successful. This goes through a
different, currently non-transactional, set of code.)
3. Since I am in Tomcat and don't actually require JTA transactions,
most likely JDBC transactions would suffice for my purposes. To this
end, my persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence>
<persistence-unit name="sats-satsDS"
transaction-type="RESOURCE_LOCAL">
<non-jta-data-source>java:comp/env/jdbc/satsDS</non-jta-data-so
urce>
<class>com.datasourceinc.sats.entity.Test1</class>
<provider>org.eclipse.persistence.jpa.PersistenceProvider</prov
ider>
<properties>
<property name="eclipselink.target-database" value="Derby"/>
<property name="eclipselink.session.customizer"
value="com.datasourceinc.springmvc.entity.JpaEclipseLinkSessionCustomize
r"/>
<property name="eclipselink.logging.level" value="FINEST"/>
</properties>
</persistence-unit>
</persistence>
(N.B. The session customizer follows the code on the EclipseLink site
example for Tomcat and Oracle. Among the issues I have not yet had time
to follow up is that both the writeConnector and the readConnector are
null at runtime.)
4. I went with Spring 3 (even though it is a milestone release - this
project may last long enough to get to GA!) because of the greater
support for annotations, but would be willing to rethink this. The JPA
annotations on the entity in question, of course, are pretty
straightforward:
package com.datasourceinc.sats.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="test1", schema="satsuser")
public class Test1
{
private Integer id;
private String value;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id")
public Integer getId()
{
return id;
}
public void setId(Integer id)
{
this.id = id;
}
@Column(name="val")
public String getValue()
{
return value;
}
public void setValue(String value)
{
this.value = value;
}
}
(N.B. Obviously, I'm just trying to get things working... :)
5. And last but not least, the session facade:
package com.datasourceinc.sats.entity;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.transaction.annotation.Transactional;
import com.datasourceinc.springmvc.entity.JpaPropertyInitializer;
import com.datasourceinc.springmvc.entity.SessionFacade;
@Transactional
public class Test1Facade implements SessionFacade<Test1, Integer>
{
@PersistenceContext
private EntityManager em;
public Test1 create(Test1 info)
{
em.persist(info);
return info;
}
// ...
}
(N.B. The interface specifies the entity and PK types using generics.)
As for calling flush() in the create method, what a great idea! I didn't
think of that. But obviously, getting the transactions actually working
would be far preferable.
If I get this working and it is of interest, I would certainly be
willing to write it up for an example on the EclipseLink site - it seems
to combine together several things that are not terribly well documented
yet.
David Sills
-----Original Message-----
From: eclipselink-users-bounces@xxxxxxxxxxx
[mailto:eclipselink-users-bounces@xxxxxxxxxxx] On Behalf Of Olaf Otto
Sent: Saturday, June 06, 2009 5:57 PM
To: EclipseLink User Discussions
Subject: Re: [eclipselink-users] Odd behavior of eclipselink entity
manager
Hello David,
From what i am seeing in the log it appears the transaction management
you are attempting to use is definitely not working.
There is no transaction commit after the persist() operation, instead
your entityManager is closed:
2009-06-06 02:38:56,970 DEBUG
[org.springframework.orm.jpa.EntityManagerFactoryU
tils] - <Closing JPA EntityManager>
[EL Finer]: 2009-06-06
02:38:56.97--UnitOfWork(2289825)--Thread(Thread[http-8080
-1,5,main])--release unit of work
[EL Finer]: 2009-06-06
02:38:56.97--ClientSession(15717886)--Thread(Thread[http-
8080-1,5,main])--client released
Thus closing the unit of work (the persistence context implementation).
This also discards any pending changes in the context.
A transaction is only opened on pre-deployment and committed immediately
before the connection pool is released at the end.
I believe you can trigger the proper SQL queries for testing purposes by
calling flush() on the EntityManager after invoking persist().
This makes me wonder:
- What type of transaction handling did you declare (in the
persistence.xml or else)? JTA or resource-local?
- How do you obtain the entity manager you are using to persist the
entity?
- What type of transaction management strategy are you using in Spring?
Also, posting your test code and the contents of the persistence.xml
might help.
Kind regards,
Olaf
David Sills wrote:
Thanks in advance for any help.
I'm trying to work through integrating EclipseLink into an application
using Spring 3 and Tomcat 6 and Derby embedded. I've been using
TopLink for a while without issues. Arranging reading was also not an
issue, and EclipseLink performed beautifully.
When I tried writing a JPA entity, however, something very odd
happens. Nothing. Increasing the logging to FINEST for Eclipse and
DEBUG for everything else suggests that the Spring transactionality is
working fine, but the odd sequence of lines below appears. It looks as
though the Entity Manager is being opened, the line "[EL Finest]:
2009-06-06
02:38:56.97--UnitOfWork(2289825)--Thread(Thread[http-8080-1,5,main])--PE
RSIST
operation called on: com.datasourceinc.sats.entity.Test1@4
6dc34", and then the Entity Manager is closed, and the transaction
committed, but no SQL is issued and nothing happens. Any ideas would
be most welcome, and of course, all questions and requests for
configuration files will be happily answered.
David Sills
2009-06-06 02:38:56,345 DEBUG
[org.springframework.beans.factory.support.Default
ListableBeanFactory] - <Returning cached instance of singleton bean
'org.springf
ramework.transaction.interceptor.TransactionInterceptor#0'>
2009-06-06 02:38:56,360 DEBUG
[org.springframework.transaction.annotation.Annota
tionTransactionAttributeSource] - <Adding transactional method
[create] with att
ribute [PROPAGATION_REQUIRED,ISOLATION_DEFAULT]>
2009-06-06 02:38:56,392 DEBUG
[org.springframework.jdbc.datasource.DataSourceTra
nsactionManager] - <Creating new transaction with name
[com.datasourceinc.spring
mvc.entity.SessionFacade.create]:
PROPAGATION_REQUIRED,ISOLATION_DEFAULT>
2009-06-06 02:38:56,392 DEBUG
[org.springframework.jdbc.datasource.DataSourceTra
nsactionManager] - <Acquired Connection [jdbc:derby:database/sats,
UserName=APP,
Apache Derby Embedded JDBC Driver] for JDBC transaction>
2009-06-06 02:38:56,423 DEBUG
[org.springframework.jdbc.datasource.DataSourceTra
nsactionManager] - <Switching JDBC Connection
[jdbc:derby:database/sats, UserNam
e=APP, Apache Derby Embedded JDBC Driver] to manual commit>
2009-06-06 02:38:56,454 DEBUG
[org.springframework.orm.jpa.EntityManagerFactoryU
tils] - <Opening JPA EntityManager>
[EL Finest]: 2009-06-06
02:38:56.454--ServerSession(29366994)--Thread(Thread[htt
p-8080-1,5,main])--Begin deploying Persistence Unit sats-satsDS; state
Predeploy
ed; factoryCount 1
[EL Finest]: 2009-06-06
02:38:56.517--ServerSession(29366994)--Thread(Thread[htt
p-8080-1,5,main])--property=eclipselink.logging.level; value=FINEST;
translated
value=FINEST
[EL Finest]: 2009-06-06
02:38:56.517--ServerSession(29366994)--Thread(Thread[htt
p-8080-1,5,main])--property=eclipselink.logging.level; value=FINEST;
translated
value=FINEST
[EL Finest]: 2009-06-06
02:38:56.517--ServerSession(29366994)--Thread(Thread[htt
p-8080-1,5,main])--property=eclipselink.target-database; value=Derby;
translated
value=org.eclipse.persistence.platform.database.DerbyPlatform
[EL Finest]: 2009-06-06
02:38:56.532--ServerSession(29366994)--Thread(Thread[htt
p-8080-1,5,main])--property=eclipselink.session.customizer;
value=com.datasource
inc.springmvc.entity.JpaEclipseLinkSessionCustomizer
JpaEclipseLinkSessionCustomizer: configured null
JpaEclipseLinkSessionCustomizer: configured null
[EL Info]: 2009-06-06
02:38:56.548--ServerSession(29366994)--Thread(Thread[http-
8080-1,5,main])--EclipseLink, version: Eclipse Persistence Services -
1.1.0.r363
4
[EL Config]: 2009-06-06
02:38:56.579--ServerSession(29366994)--Connection(221467
97)--Thread(Thread[http-8080-1,5,main])--connecting(DatabaseLogin(
platform=>DerbyPlatform
user name=> ""
connector=>JNDIConnector datasource name=>null
))
[EL Config]: 2009-06-06
02:38:56.595--ServerSession(29366994)--Connection(333309
51)--Thread(Thread[http-8080-1,5,main])--Connected:
jdbc:derby:database/sats
User: APP
Database: Apache Derby Version: 10.5.1.1 - (764942)
Driver: Apache Derby Embedded JDBC Driver Version: 10.5.1.1 - (764942)
[EL Config]: 2009-06-06
02:38:56.595--ServerSession(29366994)--Connection(206802
2)--Thread(Thread[http-8080-1,5,main])--connecting(DatabaseLogin(
platform=>DerbyPlatform
user name=> ""
connector=>JNDIConnector datasource name=>null
))
[EL Config]: 2009-06-06
02:38:56.595--ServerSession(29366994)--Connection(284128
51)--Thread(Thread[http-8080-1,5,main])--Connected:
jdbc:derby:database/sats
User: APP
Database: Apache Derby Version: 10.5.1.1 - (764942)
Driver: Apache Derby Embedded JDBC Driver Version: 10.5.1.1 - (764942)
[EL Finest]: 2009-06-06
02:38:56.689--ServerSession(29366994)--Thread(Thread[htt
p-8080-1,5,main])--sequencing connected, state is
NoPreallocation_State
[EL Finest]: 2009-06-06
02:38:56.689--ServerSession(29366994)--Thread(Thread[htt
p-8080-1,5,main])--sequence SEQ_GEN_IDENTITY: preallocation size 1
[EL Info]: 2009-06-06
02:38:56.86--ServerSession(29366994)--Thread(Thread[http-8
080-1,5,main])--file:/C:/apache-tomcat-6.0.18/temp/7-sats/WEB-INF/lib/sa
ts.jar-s
ats-satsDS login successful
[EL Finest]: 2009-06-06
02:38:56.86--ServerSession(29366994)--Thread(Thread[http
-8080-1,5,main])--End deploying Persistence Unit sats-satsDS; state
Deployed; fa
ctoryCount 1
2009-06-06 02:38:56,923 DEBUG
[org.springframework.orm.jpa.EntityManagerFactoryU
tils] - <Registering transaction synchronization for JPA
EntityManager>
[EL Finer]: 2009-06-06
02:38:56.97--ServerSession(29366994)--Thread(Thread[http-
8080-1,5,main])--client acquired
[EL Finest]: 2009-06-06
02:38:56.97--UnitOfWork(2289825)--Thread(Thread[http-808
0-1,5,main])--PERSIST operation called on:
com.datasourceinc.sats.entity.Test1@4
6dc34.
2009-06-06 02:38:56,970 DEBUG
[org.springframework.orm.jpa.EntityManagerFactoryU
tils] - <Closing JPA EntityManager>
[EL Finer]: 2009-06-06
02:38:56.97--UnitOfWork(2289825)--Thread(Thread[http-8080
-1,5,main])--release unit of work
[EL Finer]: 2009-06-06
02:38:56.97--ClientSession(15717886)--Thread(Thread[http-
8080-1,5,main])--client released
2009-06-06 02:38:56,970 DEBUG
[org.springframework.jdbc.datasource.DataSourceTra
nsactionManager] - <Initiating transaction commit>
2009-06-06 02:38:56,985 DEBUG
[org.springframework.jdbc.datasource.DataSourceTra
nsactionManager] - <Committing JDBC transaction on Connection
[jdbc:derby:databa
se/sats, UserName=APP, Apache Derby Embedded JDBC Driver]>
2009-06-06 02:38:56,985 DEBUG
[org.springframework.jdbc.datasource.DataSourceTra
nsactionManager] - <Releasing JDBC Connection
[jdbc:derby:database/sats, UserNam
e=APP, Apache Derby Embedded JDBC Driver] after transaction>
2009-06-06 02:38:56,985 DEBUG
[org.springframework.jdbc.datasource.DataSourceUti
ls] - <Returning JDBC Connection to DataSource>
------------------------------------------------------------------------
_______________________________________________
eclipselink-users mailing list
eclipselink-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/eclipselink-users
_______________________________________________
eclipselink-users mailing list
eclipselink-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/eclipselink-users
_______________________________________________
eclipselink-users mailing list
eclipselink-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/eclipselink-users