Armin, you are correct. The same connection object is being used by the insert and the PK query. I went back to my test app, closing the statement for the insert before creating a new statement for the PK query, and it worked there. However, the problem remains in OJB: the PK query returns nothing.
FYI, I am now on OJB 1.5. Am having to run with compiled source since the Jakarta version is not debug enabled.
Let me focus precisely on the problem. I have modified JdbcAccessImpl.executeInsert() to include the statements needed to retrieve the PK from the insert. I know it works because I've executed it with test code without OJB. This code is for my own testing purposes and once I have solved the problem, I will revert to the release version JAR files.
Here's the function as I'm testing it. Note the statements under harvestReturnValues() are the test code as would be executed by SequenceManagerNativeImpl. The ResultSet contains null.
public void executeInsert(ClassDescriptor cld, Object obj) throws PersistenceBrokerException
{
if(logger.isDebugEnabled()) logger.safeDebug("executeInsert", obj);
PreparedStatement stmt = null;
try
{
stmt = broker.serviceStatementManager().getInsertStatement(cld);
if (stmt == null)
{
logger.error("getInsertStatement returned a null statement");
throw new PersistenceBrokerException("getInsertStatement returned a null statement");
}
broker.serviceStatementManager().bindInsert(stmt, cld, obj);
if (logger.isDebugEnabled())
logger.debug("executeInsert: " + stmt);stmt.executeUpdate();
// Harvest any return values.
harvestReturnValues(cld.getInsertProcedure(), obj, stmt);// This is the code that returns null for the PK. Works in test system, not with OJB.
Connection connection = stmt.getConnection();
stmt.close();
Statement statement = connection.createStatement();
ResultSet rs = statement.executeQuery("SELECT SCOPE_IDENTITY()");
while (rs.next())
{
long val = rs.getLong(1);
System.out.println("PK=" + val);
}
}
catch (PersistenceBrokerException e)
{
logger.error(
"PersistenceBrokerException during the execution of the insert: " + e.getMessage(),
e);
throw e;
}
catch (SQLException e)
{
logger.error(
"SQLException during the execution of the insert (for a "
+ cld.getClassOfObject().getName()
+ "): "
+ e.getMessage(),
e);
/**
* throw a specific type of runtime exception for a key constraint.
*/
if (SQL_STATE_KEY_VIOLATED.equals(e.getSQLState()))
{
throw new KeyConstraintViolatedException(e);
}
else
{
throw new PersistenceBrokerSQLException(e);
}
}
finally
{
broker.serviceStatementManager().closeResources(stmt, null);
}
}
I'm now wondering if my problem is related to how the connection is configured. I've played with a few settings, but maybe someone else would catch it.
Here's the OJB Properties:
# OJB.properties -- configuration of the OJB runtime environment
# Version: 1.0
# (c) 2001, 2002, 2003 Apache Software Foundation
# Author: Thomas Mahler and many others
#
#----------------------------------------------------------------------------------------
# repository file settings
#----------------------------------------------------------------------------------------
# The repositoryFile entry tells OJB to use this file as as its standard mapping
# repository. The file is looked up from the classpath.
#
repositoryFile=C:\\devel\\eclipse\\workspace\\digitalccs\\webApplication\\WEB-INF\\repository.xml
#
# If the useSerializedRepository entry is set to true, OJB tries to load a
# serialized version of the repository for performance reasons.
# if set to false, OJB always loads the xml file.
# Setting this flag to true will accelerate the startup sequence of OJB.
# If set to true changes to the repository.xml file will only be detected
# after maually deleting the repository.xml.serialized file.
useSerializedRepository=false
#
# If Repository serialization is used the entry serializedRepositoryPath defines the
# directory where the Repository is written to and read from.
# this entry is used only when the useSerializedRepository flag is set to true
#
serializedRepositoryPath=.
#
#----------------------------------------------------------------------------------------
# PersistenceBrokerFactory / PersistenceBroker
#----------------------------------------------------------------------------------------
# The PersistenceBrokerFactoryClass entry decides which concrete
# PersistenceBrokerFactory implemention is to be used.
PersistenceBrokerFactoryClass=org.apache.ojb.broker.core.PersistenceBrokerFactoryDefaultImpl
#
# The PersistenceBrokerClass entry decides which concrete PersistenceBroker
# implementation is to be served by the PersistenceBrokerFactory.
# This is the singlevm implementation:
PersistenceBrokerClass=org.apache.ojb.broker.core.PersistenceBrokerImpl
#
#
#----------------------------------------------------------------------------------------
# PersistenceBrokerFactory pool
#----------------------------------------------------------------------------------------
# PersistenceBroker pool configuration
# This pool uses the jakarta-commons-pool api.
# There you can find things described in detail.
#
# maximum number of brokers that can be borrowed from the
# pool at one time. When non-positive, there is no limit.
maxActive=100
#
# controls the maximum number of brokers that can sit idle in the
# pool (per key) at any time. When non-positive, there is no limit
maxIdle=-1
#
# max time block to get broker instance from pool, after that exception is thrown.
# When non-positive, block till last judgement
maxWait=2000
#
# indicates how long the eviction thread should sleep before "runs" of examining
# idle objects. When non-positive, no eviction thread will be launched.
timeBetweenEvictionRunsMillis=-1
#
# specifies the minimum amount of time that an broker may sit idle
# in the pool before it is eligable for eviction due to idle time.
# When non-positive, no object will be dropped from the pool due
# to idle time alone (depends on timeBetweenEvictionRunsMillis > 0)
minEvictableIdleTimeMillis=1000000
#
# specifies the behaviour of the pool when broker capacity is
# exhausted (see maxActive above)
# 0 - fail
# 1 - block
# 2 - grow
whenExhaustedAction=1
#
#
#----------------------------------------------------------------------------------------
# ConnectionFactory / Default ConnectionPool
#----------------------------------------------------------------------------------------
# The ConnectionFactoryClass entry determines which kind of ConnectionFactory
# is to be used within org.apache.ojb as connection factory.
# A ConnectionFactory is responsible for creating
# JDBC Connections. Current version ships four implementations:
#
# 1. ConnectionFactoryNotPooledImpl
# No pooling, no playing around.
# Every connection request returns a new connection,
# every connection release close the connection.
# 2. ConnectionFactoryPooledImpl
# This implementation supports connection pooling.
# 3. ConnectionFactoryDBCPImpl
# Using the jakarta-DBCP api for connection management, support
# connection- and prepared statement-pooling, abandoned connection handling.
# 4. ConnectionFactoryManagedImpl
# Connection factory for use within managed environments - e.g. JBoss.
# Every obtained DataSource was wrapped within OJB (and ignore
# e.g. con.commit() calls within OJB).
# Use this implementation e.g if you use Datasources from an application server.
#
# Use the OJB performance tests to decide, which implementation is best for you.
# The proper way of obtaining a connection is configured in
# JDBCConnectionDescriptor entries in the repository.xml file.
# If want a more fine grained control of each connection pool used by OJB,
# take a look at the repository.dtd, there was a possibility to override
# this default connection factory entry in each JDBCConnectionDescriptor.
#
ConnectionFactoryClass=org.apache.ojb.broker.accesslayer.ConnectionFactoryPooledImpl
#ConnectionFactoryClass=org.apache.ojb.broker.accesslayer.ConnectionFactoryNotPooledImpl
#ConnectionFactoryClass=org.apache.ojb.broker.accesslayer.ConnectionFactoryManagedImpl
#ConnectionFactoryClass=org.apache.ojb.broker.accesslayer.ConnectionFactoryDBCPImpl
#
#
#----------------------------------------------------------------------------------------
# ConnectionManager
#----------------------------------------------------------------------------------------
# The ConnectionManagerClass entry defines the ConnectionManager implemementation to be used
ConnectionManagerClass=org.apache.ojb.broker.accesslayer.ConnectionManagerImpl
#
#
#----------------------------------------------------------------------------------------
# SqlGenerator
#----------------------------------------------------------------------------------------
# The SqlGeneratorClass entry defines the SqlGenerator implemementation to be used
#Original OJB class replaced with stored-procedure aware class.
SqlGeneratorClass=org.apache.ojb.broker.accesslayer.sql.SqlGeneratorDefaultImpl
#
#
#----------------------------------------------------------------------------------------
# CollectionProxy class
#----------------------------------------------------------------------------------------
# The optional CollectionProxy entry defines the class to be used for CollectionProxies
# if this entry is null org.apache.ojb.broker.accesslayer.ListProxy is used for Lists
# and org.apache.ojb.broker.accesslayer.CollectionProxy for Collections
#
#CollectionProxyClass=
#
#----------------------------------------------------------------------------------------
# StatementManager
#----------------------------------------------------------------------------------------
# The StatementManagerClass entry defines the StatementManager implemementation to be used
#Original OJB class replaced with stored-procedure aware class.
StatementManagerClass=org.apache.ojb.broker.accesslayer.StatementManager
#
#
#----------------------------------------------------------------------------------------
# StatementsForClass
#----------------------------------------------------------------------------------------
# The StatementsForClassClass entry defines the StatementsForClass implemementation to be used
# to implement cached statements.
StatementsForClassClass=org.apache.ojb.broker.accesslayer.StatementsForClassImpl
#
#
#----------------------------------------------------------------------------------------
# JdbcAccess
#----------------------------------------------------------------------------------------
# The JdbcAccessClass entry defines the JdbcAccess implemementation to be used
#Original OJB class replaced with stored-procedure aware class.
JdbcAccessClass=org.apache.ojb.broker.accesslayer.JdbcAccessImpl
#
#
#----------------------------------------------------------------------------------------
# Object cache
#----------------------------------------------------------------------------------------
# The ObjectCacheClass entry tells OJB which concrete instance Cache
# implementation is to be used.
ObjectCacheClass=org.apache.ojb.broker.cache.ObjectCacheDefaultImpl
#ObjectCacheClass=org.apache.ojb.broker.cache.ObjectCacheEmptyImpl
#ObjectCacheClass=org.apache.ojb.broker.cache.ObjectCachePerBrokerImpl
#ObjectCacheClass=org.apache.ojb.broker.cache.MetaObjectCacheJCSImpl
#ObjectCacheClass=org.apache.ojb.broker.cache.MetaObjectCachePerClassImpl
#
#
# Use CacheFilters to do filter operations before caching methods were
# called. Build your own filter class by implementing org.apache.ojb.cache.CacheFilter.
# It is possible to use a arbitrary number of CacheFilters, but this slows
# down the performance of the cache, thus handle with care.
#
# - org.apache.ojb.broker.cache.CacheFilterClassImpl
# allows filtering of classes
# - org.apache.ojb.broker.cache.CacheFilterPackageImpl
# allows filtering of packages
# More info see Javadoc of the according classes.
# Set a comma separated list of CacheFilter.
#ObjectCacheFilter=org.apache.ojb.broker.cache.CacheFilterClassImpl,org.apache.ojb.broker.cache.CacheFilterPackageImpl
#
#----------------------------------------------------------------------------------------
# Locking
#----------------------------------------------------------------------------------------
# The LockManagerClass entry tells OJB which concrete LockManager
# implementation is to be used.
LockManagerClass=org.apache.ojb.odmg.locking.LockManagerDefaultImpl
#
# The LockMapClass entry tells OJB which concrete LockMap
# implementation is to be used.
# If OJB is running on multiple concurrent clients it is recommended
# to use the PersistentLockMapImpl. It guarantees to provide
# Lockamanagement across multiple JVMs.
# If OJB is running in a single JVM (e.g. in a desktop app, or in a servlet
# engine) it is save to use the InMemoryLockMapImpl. Using it will result
# in a large performance gain.
# LockMapClass=org.apache.ojb.odmg.locking.PersistentLockMapImpl
LockMapClass=org.apache.ojb.odmg.locking.InMemoryLockMapImpl
#
# The LockTimeout entry defines the maximum time in milliseconds
# that a lock may be hold. Defaults to 60000 = 1 minute
LockTimeout=60000
#
# The ImplicitLocking entry defines if implicit lock acquisition is
# to be used. If set to true OJB implicitely locks objects to ODMG
# transactions after performing OQL queries.
# If implicit locking is used locking objects is recursive, that is
# associated objects are also locked.
# If ImplicitLocking is set to false, no locks are obtained in OQL
# queries and there is also no recursive locking.
ImplicitLocking=true
#ImplicitLocking=false
#
# The LockAssociations entry defines the behaviour for the OJB
# implicit locking feature. If set to WRITE (default) acquiring a write-
# lock on a given object x implies write locks on all objects associated
# to x. If set to READ implicit read-locks are acquired.
# Acquiring a read-lock on x thus allways results in implicit read-locks
# on all associated objects.
#LockAssociations=READ
LockAssociations=WRITE
#
#
#----------------------------------------------------------------------------------------
# Logging
#----------------------------------------------------------------------------------------
# The LoggerClass entry tells OJB which concrete Logger
# implementation is to be used.
#
# Commons-logging
LoggerClass=org.apache.ojb.broker.util.logging.CommonsLoggerImpl
# log4j based logging
#LoggerClass=org.apache.ojb.broker.util.logging.Log4jLoggerImpl
# OJB's own simple looging support
#LoggerClass=org.apache.ojb.broker.util.logging.PoorMansLoggerImpl
LoggerConfigFile=WEB-INF/dccslogging.properties
#
# The LogLevel entries tells OJB which LogLevels are active
# for the different loggers used within OJB
# Loglevels: DEBUG < INFO < WARN < ERROR < FATAL
# That is loglevel WARN won't log DEBUG and INFO messages,
# but will log WARN, ERROR, and FATAL messages
#
# Global default log level used for all logging
# entities if not specified
ROOT.LogLevel=WARN
#
# The Default Logger instance used within OJB
DEFAULT.LogLevel=WARN
# Logger for PersistenceBrokerImpl class
org.apache.ojb.broker.core.PersistenceBrokerImpl.LogLevel=WARN
# Logger for PersistenceBrokerFactory class
org.apache.ojb.broker.PersistenceBrokerFactory.LogLevel=WARN
# Logger for RepositoryXmlHandler, useful for debugging parsing of repository.xml!
org.apache.ojb.broker.metadata.RepositoryXmlHandler.LogLevel=WARN
# Logger for JdbcAccess, useful for debugging JDBC related problems
org.apache.ojb.broker.accesslayer.JdbcAccessImpl.LogLevel=WARN
# Logger for RsIterator, useful for debugging problems with Object materialization
org.apache.ojb.broker.accesslayer.RsIterator.LogLevel=WARN
# Logger for StatementsForClass, useful for debugging JDBC Connection related problems
org.apache.ojb.broker.accesslayer.StatementsForClassImpl.LogLevel=WARN
# Logger for SqlGenerator, useful for debugging generation of SQL
org.apache.ojb.broker.accesslayer.sql.SqlGeneratorDefaultImpl.LogLevel=WARN
# Logger for RepositoryPersistor
org.apache.ojb.broker.metadata.RepositoryPersistor.LogLevel=WARN
# Logger for PersistenceBrokerFactoryDefaultImpl
org.apache.ojb.broker.core.PersistenceBrokerFactoryDefaultImpl.LogLevel=WARN
# Logger for ConnectionFactory
org.apache.ojb.broker.accesslayer.ConnectionFactoryAbstractImpl.LogLevel=ERROR
#
# Special Logger categories used in test suite and tutorials
#
# Logger for the ODMG Implementation
ODMG.LogLevel=WARN
# Logger for the JDO RI Implementation
JDO.LogLevel=DEBUG
# Logger for the performance tests
performance.LogLevel=INFO
# Logger for the soda api
soda.LogLevel=WARN
# Logger for the factory service
ConfigurableFactory.LogLevel=WARN
#
#
#----------------------------------------------------------------------------------------
# OQL / SQL settings
#----------------------------------------------------------------------------------------
# The OqlCollectionClass entry defines the collection type returned
# from OQL queries. By default this value is set to DListImpl.
# This will be good for most situations as DList allows maximum flexibility
# in a ODMG environment.
# Using DLists for large resultsets may be bad for application performance.
# For these scenarios you can use ArrayLists or Vectors.
# Important note: the collections class to be used MUST implement the
# interface org.apache.ojb.broker.ManageableCollection.
#
OqlCollectionClass=org.apache.ojb.odmg.collections.DListImpl
# OqlCollectionClass=org.apache.ojb.broker.util.collections.ManageableArrayList
# OqlCollectionClass=org.apache.ojb.broker.util.ManageableVector
#
# The SqlInLimit entry limits the number of values in IN-sql statement,
# -1 for no limits. This hint is used in Criteria.
SqlInLimit=2000
#
#
#----------------------------------------------------------------------------------------
# Meta data / mapping settings
#----------------------------------------------------------------------------------------
# The PersistentFieldClass property defines the implementation class
# for PersistentField attributes used in the OJB MetaData layer.
# By default the best performing attribute/refection based implementation
# is selected (PersistentFieldDirectAccessImpl).
#
# - PersistentFieldDirectAccessImpl
# is a high-speed version of the access strategies.
# It does not cooperate with an AccessController,
# but accesses the fields directly. Persistent
# attributes don't need getters and setters
# and don't have to be declared public or protected
# - PersistentFieldPrivilegedImpl
# Same as above, but does cooperate with AccessController and do not
# suppress the java language access check.
# - PersistentFieldIntrospectorImpl
# uses JavaBeans compliant calls only to access persistent attributes.
# No Reflection is needed. But for each attribute xxx there must be
# public getXxx() and setXxx() methods.
# - PersistentFieldDynaBeanAccessImpl
# implementation used to access a property from a
# org.apache.commons.beanutils.DynaBean.
#
PersistentFieldClass=org.apache.ojb.broker.metadata.fieldaccess.PersistentFieldDirectAccessImpl
#PersistentFieldClass=org.apache.ojb.broker.metadata.fieldaccess.PersistentFieldPrivilegedImpl
#PersistentFieldClass=org.apache.ojb.broker.metadata.fieldaccess.PersistentFieldIntrospectorImpl
#PersistentFieldClass=org.apache.ojb.broker.metadata.fieldaccess.PersistentFieldDynaBeanAccessImpl
#
# outdated deprecated versions:
#PersistentFieldClass=org.apache.ojb.broker.metadata.fieldaccess.PersistentFieldMaxPerformanceImpl
#PersistentFieldClass=org.apache.ojb.broker.metadata.fieldaccess.PersistentNestedFieldMaxPerformanceImpl
#PersistentFieldClass=org.apache.ojb.broker.metadata.fieldaccess.PersistentFieldPropertyImpl
#
#----------------------------------------------------------------------------------------
# Component Intercepting for Profiling and Tracing
#----------------------------------------------------------------------------------------
# By enabling an InterceptorClass all OJB components will use
# this Interceptor. Interceptors allow advanced tracing and Profiling
# of all component method calls.
# This is currently an experimental feature useful only for OJB kernel developers.
#
#InterceptorClass=org.apache.ojb.broker.util.interceptor.TracingInterceptor
#
#----------------------------------------------------------------------------------------
# Transaction Management and assocation
#----------------------------------------------------------------------------------------
# Use the LocalTxManager if you want the transaction to be associated by a thread
OJBTxManagerClass=org.apache.ojb.odmg.LocalTxManager
# Use the JTATxManager if you want the transaction to be associated via the Transaction
# manager that is in your application server.
#OJBTxManagerClass=org.apache.ojb.odmg.JTATxManager
#
# The TransactionManager is acquired in different ways dependent on the application server.
# The JTATransactionManagerClass property allows you to specify the class that implements
# the proper behaviour for finding the transaction manager. Only use when OJBTxManagerClass
# is set to a factory that uses the application server transaction manager
# (org.apache.ojb.odmg.JTATxManager)
#
# JBoss Transaction Manager Factory
JTATransactionManagerClass=org.apache.ojb.odmg.transaction.JBossTransactionManagerFactory
# Weblogic Transaction Manager Factory
#JTATransactionManagerClass=org.apache.ojb.odmg.transaction.WeblogicTransactionManagerFactory
# WebSphere transaction manager factory
#JTATransactionManagerClass=org.apache.ojb.odmg.transaction.WebSphereTransactionManagerFactory
# Orion transaction manager factory
#JTATransactionManagerClass=org.apache.ojb.odmg.transaction.OrionTransactionManagerFactory
#
#----------------------------------------------------------------------------------------
# End of OJB.properties file
#----------------------------------------------------------------------------------------
Here's the Respository.xml file
<?xml version="1.0" encoding="UTF-8"?>
<!-- Repository for the Apache ObJectRelationalBridge (OJB) System. Generated by Torque on: [Fri Sep 12 11:40:37 EDT 2003] -->
<!-- defining entities for include-files -->
<!DOCTYPE descriptor-repository PUBLIC
"-//Apache Software Foundation//DTD OJB Repository//EN"
"repository.dtd"
[
<!ENTITY internal SYSTEM "repository_internal.xml">
<!ENTITY dccs SYSTEM "repository_dccs.xml">
]><descriptor-repository version="1.0" isolation-level="read-uncommitted">
<!-- The Default JDBC Connection. If a Class does not specify its own JDBC Connection,
the Connection specified here will be used. -->
<jdbc-connection-descriptor jcd-alias="dccs"
default-connection="true"
platform="MsSQLServer"
jdbc-level="1.0"
jndi-datasource-name="java:comp/env/jdbc/dccs"
useAutoCommit="2" ><sequence-manager
className="org.apache.ojb.broker.util.sequence.SequenceManagerNativeImpl">
</sequence-manager>
</jdbc-connection-descriptor>
<!-- include internal mappings here --> &internal;
<!-- include mappings here --> &dccs;
</descriptor-repository>
And, here's the mappings for the table I'm testing with:
<!--
==============================================================
TABLE Addresses
==============================================================
Addresses
-->
<class-descriptor
class="com.digitalccs.data.models.Addresses"
table="Addresses"
refresh="true"
><!-- COLUMN Address_ID ..............................................
-->
<field-descriptor id="1"
name="addressId"
column="Address_ID"
jdbc-type="BIGINT"
nullable="false"
indexed="true"
autoincrement="true"
primarykey="true"
access="readonly"
/>
<!-- COLUMN Address1 ..............................................
-->
<field-descriptor id="2"
name="address1"
column="Address1"
jdbc-type="VARCHAR"
/>
<!-- COLUMN Address2 ..............................................
-->
<field-descriptor id="3"
name="address2"
column="Address2"
jdbc-type="VARCHAR"
/>
<!-- COLUMN Address3 ..............................................
-->
<field-descriptor id="4"
name="address3"
column="Address3"
jdbc-type="VARCHAR"
/>
<!-- COLUMN Address4 ..............................................
-->
<field-descriptor id="5"
name="address4"
column="Address4"
jdbc-type="VARCHAR"
/>
<!-- COLUMN City ..............................................
-->
<field-descriptor id="6"
name="city"
column="City"
jdbc-type="VARCHAR"
/>
<!-- COLUMN State ..............................................
-->
<field-descriptor id="7"
name="state"
column="State"
jdbc-type="VARCHAR"
/>
<!-- COLUMN Postal_Code ..............................................
-->
<field-descriptor id="8"
name="postalCode"
column="Postal_Code"
jdbc-type="CHAR"
/></class-descriptor>
From: Armin Waibel <[EMAIL PROTECTED]> Reply-To: "OJB Users List" <[EMAIL PROTECTED]> To: OJB Users List <[EMAIL PROTECTED]> Subject: Re: Primary Key from Insert Date: Thu, 18 Mar 2004 01:34:41 +0100
Hi,
Glenn Barnard wrote:
Armin:
My suspicions are confirmed. JdbcAccessImpl closes its Statement after the insert so that the SequenceManager must get another Statement (and, therefore a new connection)
why should the SequenceManager lookup a new connection after closing of the statement in JdbcAccessImpl??
The connection used by the actual PB instance was managed by ConnectionManagerImpl class, this class is responsible to release the connection after use. During a PB-transaction always the same connection was used. On begin of the tx the connection was obtained, on commit or abort the connection was released.
in order to submit the SCOPE_IDENTITY() query.
Looks like I've got some serious re-tooling to make this work!
Before I consider that, let me ask one more question:
If I do a BeginTransaction before all this, how does OJB/JDBC keep the transactions coordinated among all the Statements so that the Commit persists the data? It would seem that the broker would keep the Statement/Connection and execute all the transactions with that same object????
I don't understand again (sorry my bad understanding english)
transactions? plural? With beginTransaction you start one PB-tx. One connection will be associated with the used PB-instance. Till the abort/commitTransaction call all sql operation use the same connection.
Nested transaction are not supported.
Sorry if I couldn't help you.
regards, Armin
Thanks for being patient with me.
From: Armin Waibel <[EMAIL PROTECTED]> Reply-To: "OJB Users List" <[EMAIL PROTECTED]> To: OJB Users List <[EMAIL PROTECTED]> Subject: Re: Primary Key from Insert Date: Wed, 17 Mar 2004 17:43:02 +0100
Glenn Barnard wrote:
Armin, thanks for the direction. I've switched over to the NativeSequenceManager. It calls lastInsertSelect() which in turn invokes the supported platforms getLastInsertIdentity(). The platform it's loading is the PlatformMsSQLServerImpl and it doesn't overload PlatformDefaultImpl's stub for getLastInsertIdentity which throws a not implemented exception.
I'm back on version 1.4 and will upgrade immediately to 1.5. If that version does not have the correct getLastInsertIdentity, then I will have to look into implementing it elsewhere, perhaps by extending PlatformMsSQLServerImpl with a custom getLastInsertIdentity method that simply returns "SELECT SCOPE_IDENTITY() AS newID".
In rc5 method was not implemented.
You can also use CVS version of OJB - it's stable (98%, to check you can run OJB junit test suite) and include identity column support in PlatformMsSQLServerImpl.
regards, Armin
Thanks again for your help.
From: Armin Waibel <[EMAIL PROTECTED]> Reply-To: "OJB Users List" <[EMAIL PROTECTED]> To: OJB Users List <[EMAIL PROTECTED]> Subject: Re: Primary Key from Insert Date: Wed, 17 Mar 2004 15:49:44 +0100
Hi Glenn,
why don't you use a identity based sequence manager implementation?
http://db.apache.org/ojb/sequencemanager.html#nativeSequenceManager
(seems that one part of this section was "corrupted" by Maven, with "ant htmldoc" you can generate the local documentation)
or your persistent capable objects can implement PersistenceBrokerAware interface and you assign the PK by hand in the afterInsert method (obtain connection from PB instance and perform sql query by your own).
regards, Armin
Glenn Barnard wrote:
I'm using SQL Server 2000 and need to get the primary key returned in the data model after an insert. My research shows that the query "SELECT SCOPE_IDENTITY() AS newID" needs to be executed. What do I need to do to get OJB to automatically populate the PK field in the data model it returns?
_________________________________________________________________
Get tax tips, tools and access to IRS forms � all in one place at MSN Money! http://moneycentral.msn.com/tax/home.asp
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
_________________________________________________________________
Free up your inbox with MSN Hotmail Extra Storage. Multiple plans available. http://click.atdmt.com/AVE/go/onm00200362ave/direct/01/
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
_________________________________________________________________
Get reliable access on MSN 9 Dial-up. 3 months for the price of 1! (Limited-time offer) http://click.atdmt.com/AVE/go/onm00200361ave/direct/01/
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
_________________________________________________________________
Is your PC infected? Get a FREE online computer virus scan from McAfee� Security. http://clinic.mcafee.com/clinic/ibuy/campaign.asp?cid=3963
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
