Hi Aleksandar,

Milisic Aleksandar wrote:
Armin, after your request to post to the user group, I
am doing that, even though I thought last time that if
I clicked the reply at the bottom it would
automatically be posted to the newsgroup. Silly me. :)

Anyway, here is my original question and with it the
additional info you asked for. Anybody else who has
maybe had these problems, feel free to enlighten me.
:)

thanks for the detailed description - exemplary ;-)

First thing I notice is that PersonContainer has autoincrement="true" for it's PK field, but in Person the autoincrement setting of the PK field is not specified (default is 'false'). Do you set the PK by your own or is this a bug?

The enterNewPerson(PersonContainer...)-method doesn't look fine. If you lock the PersonContainer object before start adding Person objects, OJB will detect the new Person objects on tx.commit()/checkpoint()/flush() call.

The enterNewPersonContainer-method should work when the Person PK is correct set (by hand or by autoincrement).

On the other hand you don't use the potential of the odmg-api, because you always open/close the tx within each method. If you handle the tx-demarcation outside of the methods, the methods will be more adjustable and you will be able to insert a new PersonContainer, add new Persons, ... and at the end you can completely rollback if needed. For example:

public void enterNewPersonContainer(PersonContainer container)
{
  Transaction tx = getRunningTransaction();
  Database db = odmg.getDatabase(null);
  // 4. make persistent new object
  db.makePersistent(container);
}

public void enterNewPerson(PersonContainer container, Person p)
{
  Transaction tx = getRunningTransaction();
  Database db = odmg.getDatabase(null);
  if(container != null)
  {
    // first lock
    tx.lock(container, Tran..WRITE);
    // now add new person
    container.addPerson(p);
    // OJB will detect the new person automatically
    // but you could call makePersistent(...) too
    // db.makePersistent(p);
  }
  else
  {
    // make persistent new person
    db.makePersistent(p);
  }
}

regards,
Armin





OJB VERSION: 1.0.3
MAPPING FOR PERSON AND PERSON_CONTAINER:
***************************************************
<!-- file containing the repository descriptions for
user-defined types -->
<!-- Generated by the xdoclet-ojb module -->
<class-descriptor
    class="Person"
    table="Person"

    <field-descriptor
        name="mName"
        column="mName"
        jdbc-type="VARCHAR"
        length="254"
    >
    </field-descriptor>
    <field-descriptor
        name="mPersonId"
        column="mPersonId"
        jdbc-type="INTEGER"
        primarykey="true"
    >
    </field-descriptor>
    <field-descriptor
        name="mParentPersonId"
        column="mParentPersonId"
        jdbc-type="INTEGER"
    >
    </field-descriptor>
    <field-descriptor
        name="mPersonKey"
        column="mPersonKey"
        jdbc-type="VARCHAR"
        length="254"
    >
    </field-descriptor>
    <field-descriptor
        name="mContainerId"
        column="mContainerId"
        jdbc-type="INTEGER"
    >
    </field-descriptor>
</class-descriptor>
<class-descriptor
    class="PersonContainer"
    table="PersonContainer"

    <field-descriptor
        name="mId"
        column="mId"
        jdbc-type="INTEGER"
        primarykey="true"
        autoincrement="true"
    >
    </field-descriptor>
    <field-descriptor
        name="mName"
        column="mName"
        jdbc-type="VARCHAR"
        length="254"
    >
    </field-descriptor>
    <field-descriptor
        name="mDescription"
        column="mDescription"
        jdbc-type="VARCHAR"
        length="254"
    >
    </field-descriptor>
    <collection-descriptor
        name="mPersons"
        element-class-ref="Person"
        auto-retrieve="true"
        auto-update="object"
        auto-delete="object"
    >
        <inverse-foreignkey field-ref="mContainerId"/>
    </collection-descriptor>
**************************************************

JDBC CONNECTION DESCRIPTOR:
*************************************************
 <!-- this connection was used as the default one
within OJB -->
    <jdbc-connection-descriptor
                jcd-alias="default"
                default-connection="true"
                platform="Oracle"
                jdbc-level="3.0"
                driver="oracle.jdbc.driver.OracleDriver"
                protocol="jdbc"
                subprotocol="oracle"
                dbalias="thin:@cetus.contecint.com.au:1521:alex"
                username="alex"
                password="alex"
                batch-mode="false"
        useAutoCommit="1"
        ignoreAutoCommitExceptions="false"
     >

        <!-- alternative cache implementations, see
docs section "Caching" -->
        <object-cache
class="org.apache.ojb.broker.cache.ObjectCacheTwoLevelImpl">
            <!-- meaning of attributes, please see
docs section "Caching" -->
            <!-- common attributes -->
            <attribute attribute-name="cacheExcludes"
attribute-value=""/>
            <!-- ObjectCacheTwoLevelImpl attributes
-->
            <attribute
attribute-name="applicationCache"
attribute-value="org.apache.ojb.broker.cache.ObjectCacheDefaultImpl"/>
            <attribute attribute-name="copyStrategy"
attribute-value="org.apache.ojb.broker.cache.ObjectCacheTwoLevelImpl$CopyStrategyImpl"/>
            <!-- ObjectCacheDefaultImpl attributes -->
            <attribute attribute-name="timeout"
attribute-value="900"/>
            <attribute attribute-name="autoSync"
attribute-value="true"/>
            <attribute attribute-name="cachingKeyType"
attribute-value="0"/>
            <attribute
attribute-name="useSoftReferences"
attribute-value="true"/>
        </object-cache>

        <!-- more info, see section "Connection
Handling" in docs -->
        <connection-pool
            maxActive="30"
            validationQuery=""
            testOnBorrow="true"
            testOnReturn="false"
            whenExhaustedAction="0"
            maxWait="10000"
        />

        <!-- alternative sequence manager
implementations, see docs section "Sequence Manager"
-->
        <sequence-manager
className="org.apache.ojb.broker.util.sequence.SequenceManagerHighLowImpl">
            <!-- meaning of attributes, please see
docs section "Sequence Manager" -->
            <attribute attribute-name="grabSize"
attribute-value="20"/>
            <attribute attribute-name="autoNaming"
attribute-value="true"/>
            <attribute attribute-name="sequenceStart"
attribute-value="0"/>
            <attribute
attribute-name="globalSequenceId"
attribute-value="false"/>
        </sequence-manager>
   </jdbc-connection-descriptor>

***************************************************



THE ORIGINAL QUESTION:


BUT, I do have another problem now. When I am adding

a

new PersonContainer, I add some Persons to it and

try

to write it to the database but I get an exception.

Here is the code:

==================================================
public void enterNewPersonContainer(PersonContainer
container)
{
Transaction tx2 = odmg.newTransaction();
       Database db = odmg.getDatabase(null); //the
current DB
tx2.begin();
       //broker.commitTransaction();
       // 4. make persistent new object
       db.makePersistent(container);

       // 5. commit transaction
       tx2.commit();
}
=============================================






Note that PersonContainer is a new container with
several persons added to it's internal collection.
The exception I get is the following:

==================================================
org.apache.ojb.odmg.TransactionImpl] ERROR: Could

not

prepare for commit: SQL failure while insert object
data for class Person, PK of the given object is [
mPersonId=1], object was [1] person

PersonKey: key           ParentId: 0, exception
message is [ORA-00001: unique constraint
(ALEX.PERSON_PK) violated
], SQL code [23000]
[org.apache.ojb.odmg.TransactionImpl] ERROR: Error
while commit objects, do abort tx
[EMAIL PROTECTED], SQL
failure while insert object data for class Person,

PK

of the given object is [ mPersonId=1], object was

[1]

person PersonKey: key ParentId: 0, exception message is [ORA-00001: unique
constraint (ALEX.PERSON_PK) violated
], SQL code [23000]
SQL failure while insert object data for class

Person,

PK of the given object is [ mPersonId=1], object was
[1] person PersonKey: key

   ParentId: 0, exception message is [ORA-00001:
unique constraint (ALEX.PERSON_PK) violated
], SQL code [23000]


org.apache.ojb.broker.KeyConstraintViolatedException:

SQL failure while insert object data for class

Person,

PK of the given object is [ mPersonId=1], object was
[1] person PersonKey: key ParentId: 0, exception message is [ORA-00001: unique
constraint (ALEX.PERSON_PK) violated
], SQL code [23000]
       at


org.apache.ojb.broker.accesslayer.JdbcAccessImpl.executeInsert(JdbcAccessImpl.java:266)

       at


org.apache.ojb.broker.core.PersistenceBrokerImpl.storeToDb(PersistenceBrokerImpl.java:1754)

       at


org.apache.ojb.broker.core.PersistenceBrokerImpl.store(PersistenceBrokerImpl.java:813)

       at


org.apache.ojb.broker.core.PersistenceBrokerImpl.store(PersistenceBrokerImpl.java:1687)

       at


org.apache.ojb.broker.core.DelegatingPersistenceBroker.store(DelegatingPersistenceBroker.java:181)

       at


org.apache.ojb.broker.core.DelegatingPersistenceBroker.store(DelegatingPersistenceBroker.java:181)

       at


org.apache.ojb.odmg.ObjectEnvelope.doInsert(ObjectEnvelope.java:739)

       at


org.apache.ojb.odmg.states.StateNewDirty.commit(StateNewDirty.java:106)

       at


org.apache.ojb.odmg.ObjectEnvelopeTable.writeAllEnvelopes(ObjectEnvelopeTable.java:243)

       at


org.apache.ojb.odmg.ObjectEnvelopeTable.writeObjects(ObjectEnvelopeTable.java:185)

       at


org.apache.ojb.odmg.TransactionImpl.doWriteObjects(TransactionImpl.java:370)

       at


org.apache.ojb.odmg.TransactionImpl.prepareCommit(TransactionImpl.java:687)

       at


org.apache.ojb.odmg.TransactionImpl.commit(TransactionImpl.java:623)

       at


TransactionHandler.enterNewModelContainer(TransactionHandler.java:419)

       at


TransactionHandler.enterNewModelContainer(TransactionHandler.java:388)

       at Main.run(Main.java:157)
       at Main.main(Main.java:36)
Caused by: java.sql.SQLException: ORA-00001: unique
constraint (ALEX.MODEL_PK) violated

       at


oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:125)

       at


oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:305)

       at


oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:272)

       at


oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:626)

       at


oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:182)

       at


oracle.jdbc.driver.T4CPreparedStatement.execute_for_rows(T4CPreparedStatement.java:792)

       at


oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1033)

       at


oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:2885)

       at


oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:2957)

       at


org.apache.ojb.broker.accesslayer.JdbcAccessImpl.executeInsert(JdbcAccessImpl.java:216)

       ... 16 more
====================================================


The problem seems to be the fact that it is trying

to

enter the person before the personcontainer.
I managed to get around it by doing this:

===================================================
public void enterNewPerson(PersonContainer

container)

{
      TransactionExt tx =
(TransactionExt)odmg.newTransaction();
       Database db = odmg.getDatabase(null); //the
current DB
tx.begin();
       PersistenceBroker broker = tx.getBroker();
       broker.beginTransaction();
       broker.store(container);
Iterator it =
container.getPersons().iterator();

       while( it.hasNext())
       {
           Object person = it.next();
           broker.store(person);
       }
       broker.serviceBrokerHelper().link(container,
true);

       broker.commitTransaction();
       // 4. make persistent new object
       db.makePersistent(container);

       tx.commit();
}
==================================================


I would however like to be able to do this in an
easier way, if possible of course, rather than

looping

through all the persons, commiting them and then
commiting the container. And I would like to stick

to

using odmg api, if possible.

Is there a way to do this?


p.s. Sorry if my formatting is bad, I am trying to
improve it since I haven't used these kinds of

mailing

lists before.


Thank you.



        

        
                
____________________________________________________ Do you Yahoo!? Yahoo! Photos: Now with unlimited storage http://au.photos.yahoo.com

---------------------------------------------------------------------
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]

Reply via email to