Hallo,
I'm using db-ojb-1.0.rc4 with Microsoft SQL Server 2000.
Look at my OJB.properties file.
repositoryFile=repository.xml
useSerializedRepository=false
serializedRepositoryPath=.
PersistenceBrokerFactoryClass=org.apache.ojb.broker.core.PersistenceBrokerFactoryDefaultImpl
PersistenceBrokerClass=org.apache.ojb.broker.core.PersistenceBrokerImpl
maxActive=100
maxIdle=-1
maxWait=2000
timeBetweenEvictionRunsMillis=-1
minEvictableIdleTimeMillis=1000000
whenExhaustedAction=0
ConnectionFactoryClass=org.apache.ojb.broker.accesslayer.ConnectionFactoryPooledImpl
ConnectionManagerClass=org.apache.ojb.broker.accesslayer.ConnectionManagerImpl
SqlGeneratorClass=org.apache.ojb.broker.accesslayer.sql.SqlGeneratorDefaultImpl
StatementManagerClass=org.apache.ojb.broker.accesslayer.StatementManager
StatementsForClassClass=org.apache.ojb.broker.accesslayer.StatementsForClassImpl
JdbcAccessClass=org.apache.ojb.broker.accesslayer.JdbcAccessImpl
ObjectCacheClass=org.apache.ojb.broker.cache.ObjectCacheEmptyImpl
LockManagerClass=org.apache.ojb.odmg.locking.LockManagerDefaultImpl
LockMapClass=org.apache.ojb.odmg.locking.InMemoryLockMapImpl
LockTimeout=60000
ImplicitLocking=true
LockAssociations=WRITE
OqlCollectionClass=org.apache.ojb.broker.util.collections.ManageableArrayList
SqlInLimit=200
PersistentFieldClass=org.apache.ojb.broker.metadata.fieldaccess.PersistentFieldIntrospectorImpl
OJBTxManagerClass=org.apache.ojb.odmg.LocalTxManager
JTATransactionManagerClass=org.apache.ojb.odmg.transaction.JBossTransactionManagerFactory
The id fields are identity columns. I'm using the plattform myMsSQLServer. This class
extends the PlatformMsSQLServerImpl, so getting the last id works with the
SequenceManagerNativeImpl.
public class PlatformmyMsSQLServerImpl extends PlatformMsSQLServerImpl
{
private static final String LAST_INSERT = "SELECT IDENT_CURRENT(''{0}'') ";
public String getLastInsertIdentityQuery(String tableName)
{
String msg = LAST_INSERT;
Object[] arguments = { tableName.toUpperCase() };
msg = MessageFormat.format( msg, arguments );
return msg;
}
}
If i use the PlatformMsSQLServerImpl the following exception occurs.
java.lang.UnsupportedOperationException: This feature is not supported by this
implementation
at
org.apache.ojb.broker.platforms.PlatformDefaultImpl.getLastInsertIdentityQuery(Unknown
Source)
at
org.apache.ojb.broker.util.sequence.SequenceManagerNativeImpl.lastInsertSelect(Unknown
Source)
at
org.apache.ojb.broker.util.sequence.SequenceManagerNativeImpl.getLastInsert(Unknown
Source)
at
org.apache.ojb.broker.util.sequence.SequenceManagerNativeImpl.afterStore(Unknown
Source)
at org.apache.ojb.broker.core.PersistenceBrokerImpl.storeToDb(Unknown Source)
at org.apache.ojb.broker.core.PersistenceBrokerImpl.store(Unknown Source)
at org.apache.ojb.broker.core.PersistenceBrokerImpl.store(Unknown Source)
at org.apache.ojb.broker.core.DelegatingPersistenceBroker.store(Unknown Source)
at org.apache.ojb.broker.core.DelegatingPersistenceBroker.store(Unknown Source)
at org.apache.ojb.odmg.states.StateNewDirty.commit(Unknown Source)
at org.apache.ojb.odmg.ObjectEnvelopeTable.commitAllEnvelopes(Unknown Source)
at org.apache.ojb.odmg.ObjectEnvelopeTable.commit(Unknown Source)
at org.apache.ojb.odmg.TransactionImpl.doCommitOnObjects(Unknown Source)
at org.apache.ojb.odmg.TransactionImpl.prepare(Unknown Source)
at org.apache.ojb.odmg.TransactionImpl.commit(Unknown Source)
Look at the repository
<jdbc-connection-descriptor
jcd-alias="mydb"
default-connection="true"
platform="myMsSQLServer"
jdbc-level="2.0"
driver="com.microsoft.jdbc.sqlserver.SQLServerDriver"
protocol="jdbc"
subprotocol="microsoft:sqlserver"
dbalias="//localhost:1433;DatabaseName=test;SelectMethod=cursor"
username="user"
password="pwd"
eager-release="false"
batch-mode="false"
useAutoCommit="1"
ignoreAutoCommitExceptions="false"
>
<sequence-manager
className="org.apache.ojb.broker.util.sequence.SequenceManagerNativeImpl">
</sequence-manager>
</jdbc-connection-descriptor>
<class-descriptor
class="bo.Dislike"
table="ABNEIG"
>
<field-descriptor id="1"
name="id"
column="abid"
jdbc-type="INTEGER"
primarykey="true"
autoincrement="true"
access="readonly"
/>
<field-descriptor id="2"
name="description"
column="bez"
jdbc-type="VARCHAR"
conversion="org.apache.ojb.broker.accesslayer.conversions.BlankString2NullFieldConversion"
access="readwrite"
/>
<field-descriptor id="3"
name="shortdescription"
column="kbez"
jdbc-type="VARCHAR"
conversion="org.apache.ojb.broker.accesslayer.conversions.BlankString2NullFieldConversion"
access="readwrite"
/>
</class-descriptor>
The value objects id is initialized with -1. After the insert is done, the object has
the right id.
If I use Dlist (OqlCollectionClass=org.apache.ojb.odmg.collections.DListImpl) I get
the exception:
java.lang.NullPointerException
at
org.apache.ojb.broker.util.sequence.AbstractSequenceManager.getUniqueValue(Unknown
Source)
at org.apache.ojb.odmg.collections.DListImpl.generateNewId(Unknown Source)
at org.apache.ojb.odmg.collections.DListImpl.getId(Unknown Source)
at org.apache.ojb.odmg.collections.DListEntry.<init>(Unknown Source)
at org.apache.ojb.odmg.collections.DListImpl.ojbAdd(Unknown Source)
at
org.apache.ojb.broker.core.PersistenceBrokerImpl.getCollectionByQuery(Unknown Source)
at
org.apache.ojb.broker.core.PersistenceBrokerImpl.getCollectionByQuery(Unknown Source)
at
org.apache.ojb.broker.core.PersistenceBrokerImpl.getCollectionByQuery(Unknown Source)
at
org.apache.ojb.broker.core.DelegatingPersistenceBroker.getCollectionByQuery(Unknown
Source)
at
org.apache.ojb.broker.core.DelegatingPersistenceBroker.getCollectionByQuery(Unknown
Source)
at org.apache.ojb.odmg.oql.OQLQueryImpl.execute(Unknown Source)
So, I switched to ManageableArrayList
(OqlCollectionClass=org.apache.ojb.broker.util.collections.ManageableArrayList).
I get one exception in section "//creating new object after deleting" process
instruction tx.lock(dislike, TransactionImpl.WRITE).
org.odmg.LockNotGrantedException: Can not lock [EMAIL PROTECTED] [-1] for WRITE
at org.apache.ojb.odmg.TransactionImpl.lock(Unknown Source)
Explain the two used objects in this test case.
Dislike
The object stores in database, with additional methods. This object extends
DislikeValue. Giving the value in the constructor of this object, all values are
copied to this object.
DislikeValue
The getter and setter for the table.
Here is the test case.
package test;
import junit.framework.TestCase;
import org.apache.ojb.broker.util.collections.ManageableArrayList;
import org.apache.ojb.odmg.OJB;
import org.apache.ojb.odmg.TransactionImpl;
import org.odmg.Database;
import org.odmg.Implementation;
import org.odmg.ODMGException;
import org.odmg.OQLQuery;
import org.odmg.Transaction;
import bo.Dislike;
import vo.DislikeValue;
public class OJBTest extends TestCase
{
private static Implementation myOdmg = null;
private static Database myDb = null;
public OJBTest(String arg0)
{
super(arg0);
}
public static void main(String[] args)
{
junit.swingui.TestRunner.run(DislikeFactoryTest.class);
}
protected void setUp() throws Exception
{
super.setUp();
}
protected void tearDown() throws Exception
{
super.tearDown();
}
final public void testODMGAccess() {
if ( myOdmg == null )
myOdmg = OJB.getInstance();
// get odmg facade instance
if ( myDb == null ) {
myDb = myOdmg.newDatabase();
//open database
try
{
myDb.open( "mydb", Database.OPEN_READ_WRITE );
System.out.println( "myDb.open=" + myDb );
}
catch (ODMGException ex)
{
ex.printStackTrace();
}
}
if ( myDb == null )
assertTrue( "database not opened", false );
DislikeValue value = new DislikeValue();
value.setDescription( "TestEntry" );
value.setShortdescription( "TestEntry" );
Dislike dislike = null;
Transaction tx = null;
try {
//creating new database object
dislike = new Dislike( value );
//open transaction
tx = myOdmg.newTransaction();
tx.begin();
//acquire write lock on new object
tx.lock(dislike, TransactionImpl.WRITE);
//commiting transaction
tx.commit();
} catch( Exception lnge ) {
lnge.printStackTrace();
//rollback the transaction
tx.abort();
}
//check for id > 0
if ( dislike.getId() < 1 )
assertTrue( "id is not set. id=" + dislike.getId(), false );
//save id
int id = dislike.getId();
//edit
//getting object from database
String oqlQuery = "select del from " +
Dislike.class.getName() +
" where id = " + id;
dislike = null;
try {
OQLQuery query = myOdmg.newOQLQuery();
query.create(oqlQuery);
//DList result = (DList) query.execute();
ManageableArrayList result =
(ManageableArrayList)query.execute();
dislike = (Dislike) result.get(0);
//open transaction
tx = myOdmg.newTransaction();
tx.begin();
//acquire write lock on new object
tx.lock( dislike, TransactionImpl.WRITE );
value.setDescription( "Test" );
value.setShortdescription( "Test" );
//commiting transaction
tx.commit();
} catch( Exception lnge ) {
lnge.printStackTrace();
//rollback the transaction
tx.abort();
}
//check for presence
if ( dislike == null )
assertTrue( "dislike not found. id=" + id, false );
//delete
try {
//open transaction
tx = myOdmg.newTransaction();
tx.begin();
myDb.deletePersistent( dislike );
//commiting transaction
tx.commit();
} catch( Exception lnge ) {
lnge.printStackTrace();
//rollback the transaction
tx.abort();
}
//check for delete
try {
OQLQuery query = myOdmg.newOQLQuery();
query.create(oqlQuery);
//DList result = (DList) query.execute();
ManageableArrayList result =
(ManageableArrayList)query.execute();
if ( result.size() > 0 )
dislike = (Dislike) result.get(0);
else
dislike = null;
} catch( Exception lnge ) {
lnge.printStackTrace();
}
if ( dislike != null )
assertTrue( "dislike not deleted. id=" + id, false );
//storing new one
value = new DislikeValue();
value.setDescription( "TestEntry" );
value.setShortdescription( "TestEntry" );
//creating new object after deleting
try {
//creating new database object
dislike = new Dislike( value );
//open transaction
tx = myOdmg.newTransaction();
tx.begin();
//acquire write lock on new object
tx.lock(dislike, TransactionImpl.WRITE);
//commiting transaction
tx.commit();
} catch( Exception lnge ) {
lnge.printStackTrace();
//rollback the transaction
tx.abort();
}
//check for id > 0
if ( dislike.getId() < 1 )
assertTrue( "id is not set. id=" + dislike.getId(), false );
//delete
try {
//open transaction
tx = myOdmg.newTransaction();
tx.begin();
myDb.deletePersistent( dislike );
//commiting transaction
tx.commit();
} catch( Exception lnge ) {
//rollback the transaction
tx.abort();
lnge.printStackTrace();
}
//check for delete
try {
OQLQuery query = myOdmg.newOQLQuery();
query.create(oqlQuery);
//DList result = (DList) query.execute();
ManageableArrayList result =
(ManageableArrayList)query.execute();
if ( result.size() > 0 )
dislike = (Dislike) result.get(0);
else
dislike = null;
} catch( Exception lnge ) {
lnge.printStackTrace();
}
assertTrue( "dislike not deleted. id=" + id, false );
}
//second test
final public void testODMGStoreTwice() {
if ( myDb == null )
assertTrue( "database not opened", false );
DislikeValue value = new DislikeValue();
value.setDescription( "TestEntry1" );
value.setShortdescription( "TestEntry1" );
Dislike dislike1 = null;
Transaction tx = null;
try {
dislike1 = new Dislike( value );
tx = myOdmg.newTransaction();
tx.begin();
tx.lock(dislike1, TransactionImpl.WRITE);
tx.commit();
} catch( Exception lnge ) {
lnge.printStackTrace();
tx.abort();
}
if ( dislike1.getId() < 1 )
assertTrue( "id is not set. id=" + dislike1.getId(), false );
value = new DislikeValue();
value.setDescription( "TestEntry2" );
value.setShortdescription( "TestEntry2" );
Dislike dislike2 = null;
tx = null;
try {
dislike2 = new Dislike( value );
tx = myOdmg.newTransaction();
tx.begin();
tx.lock(dislike2, TransactionImpl.WRITE);
tx.commit();
} catch( Exception lnge ) {
lnge.printStackTrace();
tx.abort();
}
if ( dislike2.getId() < 1 )
assertTrue( "id is not set. id=" + dislike2.getId(), false );
}
}
I've integrated an second test case for storing two objects (testODMGStoreTwice).
During process the lock method of the second object the exception is thrown.
org.odmg.LockNotGrantedException: Can not lock [EMAIL PROTECTED] [-1] for WRITE
at org.apache.ojb.odmg.TransactionImpl.lock(Unknown Source)
at test.OJBTest.testODMGStoreTwice(OJBTest.java:129)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
If I use another cache implementation, e. g.
ObjectCacheClass=org.apache.ojb.broker.cache.ObjectCacheDefaultImpl, the same
exceptiona are thrown in the two test cases.
When I'm using the SequenceManagerNextValImpl, all seems to be all right, but the
value of the id is not updated. It is allways -1. I've to set the id after reading the
id from database with the setId() methode, otherwise deleting of this objects is not
possible.
<sequence-manager
className="org.apache.ojb.broker.util.sequence.SequenceManagerNextValImpl">
<attribute attribute-name="autoNaming" attribute-value="true"/>
</sequence-manager>
Does everyone has experience using MS Access Database with counter fields? I think
it's the same problem like ms sql server, with database generated ids using a data
type.
Thanks for suggestions.
Ralf
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]