Thanks so much for your quick response. I really appreciate it.
I tried adding the em.flush after the em.persist and I am still getting the
same behavior i.e.
After the insert the dto.recId which is mapped to an non primary key
IDENTITY column is not populated on the DTO
although the REC_ID exists in the database.
I dont know of course but this would lead me to believe that at the lower
level
stmt.getGeneratedKeys is not getting called to populate "non primary key"
IDENTITY Fields
I will attempt to post more detailed information in the hopes that will
help and not confuse the issue.
The Entity/DTO called INPARTMASTER actually not PART
<code>
/**
* The persistent class for the INPARTMASTER database table.
*
*/
@Entity
@Table(name="INPARTMASTER")
public class Inpartmaster implements Serializable,
Persistent<InpartmasterPK> {
private static final long serialVersionUID = 1L;
@EmbeddedId
private InpartmasterPK pk;
... more columns here
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="REC_ID")
private Integer recId;
... more columns here
</code>
InpartmasterPK
<code>
package com.ais.persistence.entities;
import java.io.Serializable;
import javax.persistence.Embeddable;
@Embeddable
public class InmasterPK implements Serializable {
private String incomp;
private String inindiv;
private String inpart;
private static final long serialVersionUID = 1L;
public InmasterPK() {
super();
}
getters/setters etc.....
}
</code
For The Data Access Object Code
The DAO is Spring @Transactional Beans. The annotation for the DAO is
@Transactional(propagation = Propagation.REQUIRED, isolation =
Isolation.DEFAULT, rollbackFor = { Exception.class })
<code>
public PK insert(DTO dto) throws Exception {
EntityManager em = getEntityManager();
em.persist(dto);
em.flush();//added to try and retrieve stmt.getGeneratedKeys
return dto.getPk();
}
</code>
I have a Manager class which wraps the DAO. This manager is also
transactional with this annotation
@Transactional(propagation = Propagation.REQUIRED, isolation =
Isolation.DEFAULT, rollbackFor = { Exception.class })
The Manager code at this point simply wraps the DAO code
<code>
public Inpartmaster insert(Inpartmaster inpartmaster) throws
InventoryException {
InpartmasterPK pk = null;
try {
//TODO: add Pre-submit validation process
//Calling JPA InpartmasterDao
pk = inpartmasterDao.insert(inpartmaster);
}
catch (Exception e) {
log.error(Utility.getStackTrace(e));
log.error(e);
throw new InventoryException(e);
}
return inpartmaster;
}
</code>
The junit code looks like
<code>
public void testInsert()
{
try {
log.info("insert");
log.info("part="+part);
manager = getManager();
pk.setIncomp(comp);
pk.setInpart(part);
dto.setPk(pk);
log.info(dto);
dto.setChgdate(new Date());
manager.insert(dto);
log.info("recId="+dto.getRecId());
assertFalse("recId is null after insert should not be",
dto.getRecId() ==
null); //fails here the recId is not being populated with something like
stmt.getGeneratedKeys
}
catch(Exception e)
{
log.error("-------------------");
log.error(Utility.getStackTrace(e));
fail(e.getMessage());
}
}
</code>
The persistence.xml looks like
<code>
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="2.0"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="airweb-JPA-J2-SNAPSHOT"
transaction-type="RESOURCE_LOCAL">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<jta-data-source>jdbc/db2svr</jta-data-source>
<class>com.ais.persistence.entities.InpartmasterPK</class>
<class>com.ais.persistence.entities.Inpartmaster</class>
...more classes here
<!-- Validation modes: AUTO, CALLBACK, NONE -->
<validation-mode>NONE</validation-mode>
<properties>
<property name="openjpa.MaxFetchDepth" value="5"/>
<property name="openjpa.jdbc.MappingDefaults"
value="StoreEnumOrdinal=false"/>
<property name="openjpa.RuntimeUnenhancedClasses"
value="unsupported"/>
<!-- these should be commented out as the
mainDataSource is passed into
the EnitityManagerFactory from spring
<property name="openjpa.ConnectionUserName"
value="XXXX"/>
<property name="openjpa.ConnectionPassword"
value="XXXXX"/>
<property name="openjpa.ConnectionURL"
value="jdbc:db2://db2svr:50001/cmsdb:driverType=4;currentSchema=CMSDB;defaultIsolationLevel=2;retrieveMessagesFromServerOnGetMessage=true;pdqProperties=executionMode(DYNAMIC),captureMode(off),allowDynamicSQL(true),pureQueryXml(C://RAD//PersistenceFrameworkUI//WebContent//META-INF//JPAUI.pdqxml);"/>
<property name="openjpa.ConnectionDriverName"
value="com.ibm.db2.jcc.DB2Driver"/>
-->
<property name="openjpa.jdbc.DBDictionary"
value="org.apache.openjpa.jdbc.sql.DB2Dictionary"/>
<property name="openjpa.Log" value="DefaultLevel=WARN,
Runtime=TRACE,
Tool=INFO, SQL=TRACE"/>
<property name="openjpa.jdbc.Schema" value="CMSDB"/>
</properties>
</persistence-unit>
</persistence>
</code>
The spring configuration is:
<code>
<bean id="mainDataSource"
class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close"
p:jdbcUrl="jdbc:db2://db2svr:50001/cmsdb:driverType=4;currentSchema=CMSDB;defaultIsolationLevel=2;retrieveMessagesFromServerOnGetMessage=true;"
p:driverClass="com.ibm.db2.jcc.DB2Driver"
p:user="XXXXX"
p:password="XXXXX"
p:connectionCustomizerClassName="com.cms.db.CmsConnectionCustomizer"
p:preferredTestQuery="/* ping */ select 1 from (values 1)"
p:initialPoolSize="0"
p:minPoolSize="0"
p:maxPoolSize="50"
p:acquireIncrement="1"
p:maxStatements="0"
p:numHelperThreads="3"
p:testConnectionOnCheckin="true"
p:testConnectionOnCheckout="true"
p:maxConnectionAge="0"
p:idleConnectionTestPeriod="25"
p:maxIdleTime="60"
p:acquireRetryAttempts="0"
p:maxIdleTimeExcessConnections="600"
/>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="mainDataSource"/>
<property name="loadTimeWeaver">
<bean
class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
</property>
<property name="jpaDialect" ref="jpaDialect"/>
<property name="jpaVendorAdapter">
<bean
class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter">
<property name="databasePlatform"
value="org.apache.openjpa.jdbc.sql.DB2Dictionary" />
</bean>
</property>
</bean>
<bean id="jpaDialect"
class="org.springframework.orm.jpa.vendor.OpenJpaDialect"/>
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory"
ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager"
proxy-target-class="true" />
<context:component-scan base-package="com.ais.persistence.entities.dao"
/>
<bean
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"
/>
<bean id="jpaInpartmasterDao"
class="com.ais.persistence.entities.dao.InpartmasterDao" />
<bean id="jpaInventoryManager"
class="com.cms.inv.InventoryManagerJPAImpl"
p:inpartmasterDao-ref="jpaInpartmasterDao"
/>
</code>
The Database version is DB2 Express C v 9.7.200.358 on a windows 7 box.
I am using jdk version jdk1.6.0_07 inside of RAD 8.0.1 to run my junit
tests.
I will respond to Kevins post with the output of the trace log which I have
turned on in my junit test.
Thanks again so much for your help.
--
View this message in context:
http://openjpa.208410.n2.nabble.com/How-to-get-generated-keys-without-requerying-the-database-tp5957346p5959949.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.