Hi Andrus,

I post on the mailing list with a new mail adress, because my provider sucks.... I will try to detail more what i do, so you can reproduce this in your test case. Maybe i'ts because you don't have prefetching or "to dep PK".

There is a relationship between MasterJob--->MasterJobAux where i checked "To Dep PK" since no ARTIST_AUX rows can exists without corresponding MasterJob.

When i fetch a MasterJob i have added a prefetch for MasterJobAux :

query.addPrefetch(MasterJob.RELATED_MASTER_JOB_AUX_PROPERTY);

Code I use to get/create/delete MasterJobAux

                protected MasterJobAux createAux(ILookupFieldCodes fieldCode, 
Short seqNo, String value) {
                        MasterJobAux aux = 
MasterJob.this.getObjectContext().newObject(MasterJobAux.class);
                        aux.setScheduleId(MasterJob.this.getScheduleId());
                        aux.setJobName(MasterJob.this.getJobName());
                        
                        aux.setJaFieldCode((int) fieldCode.getID());
                        aux.setJaSequenceNumber(seqNo);
                        aux.setJavalue(value);
                        aux.setRelatedMasterJob(MasterJob.this);

                        return aux;
                }

                protected List<MasterJobAux> fetchAuxList() throws 
OpconException {
                        return MasterJob.this.getRelatedMasterJobAux();
                }

                protected void deleteAux(MasterJobAux toDelete) throws 
OpconException {
                        MasterJob.this.removeFromRelatedMasterJobAux(toDelete);
                        
MasterJob.this.getObjectContext().deleteObject(toDelete);
                }

Cayenne XML :

        <obj-entity name="MasterJob" className="com.sma.core.api.master.MasterJob" 
dbEntityName="JMASTER" superClassName="com.sma.core.api.DataAccessObject">
                <obj-attribute name="accessCodeId" type="java.lang.Short" 
db-attribute-path="ACCESSCDID"/>
                <obj-attribute name="altenateMachine1Id" type="java.lang.Short" 
db-attribute-path="ALTMACH1ID"/>
                <obj-attribute name="altenateMachine2Id" type="java.lang.Short" 
db-attribute-path="ALTMACH2ID"/>
                <obj-attribute name="altenateMachine3Id" type="java.lang.Short" 
db-attribute-path="ALTMACH3ID"/>
                <obj-attribute name="deptartmentId" type="java.lang.Short" 
db-attribute-path="DEPTID"/>
                <obj-attribute name="estimatedRuntime" type="java.lang.Integer" 
db-attribute-path="ESTRUNTIME"/>
                <obj-attribute name="jobGroupId" type="java.lang.Short" 
db-attribute-path="JOBGROUPID"/>
                <obj-attribute name="jobName" type="java.lang.String" 
db-attribute-path="JOBNAME"/>
                <obj-attribute name="jobTypeId" type="java.lang.Short" 
db-attribute-path="JOBTYPE"/>
                <obj-attribute name="machineGroupId" type="java.lang.Short" 
db-attribute-path="MACHGRPID"/>
                <obj-attribute name="primaryMachineId" type="java.lang.Short" 
db-attribute-path="PRIMMACHID"/>
                <obj-attribute name="scheduleId" type="java.lang.Integer" 
db-attribute-path="SKDID"/>
                <obj-attribute name="shortName" type="java.lang.String" 
db-attribute-path="SHORTNAME"/>
        </obj-entity>
        <obj-entity name="MasterJobAux" className="com.sma.core.api.auxs.MasterJobAux" 
dbEntityName="JMASTER_AUX" superClassName="com.sma.core.api.DataAccessObject">
                <obj-attribute name="jaFieldCode" type="java.lang.Integer" 
db-attribute-path="JAFC"/>
                <obj-attribute name="jaSequenceNumber" type="java.lang.Short" 
db-attribute-path="JASEQNO"/>
                <obj-attribute name="javalue" type="java.lang.String" 
db-attribute-path="JAVALUE"/>
                <obj-attribute name="jobName" type="java.lang.String" 
db-attribute-path="JOBNAME"/>
                <obj-attribute name="scheduleId" type="java.lang.Integer" 
db-attribute-path="SKDID"/>
        </obj-entity>


        <db-relationship name="toMasterJobAux" source="JMASTER" target="JMASTER_AUX" 
toDependentPK="true" toMany="true">
                <db-attribute-pair source="SKDID" target="SKDID"/>
                <db-attribute-pair source="JOBNAME" target="JOBNAME"/>
        </db-relationship>

        <obj-relationship name="relatedMasterJobAux" source="MasterJob" 
target="MasterJobAux" db-relationship-path="toMasterJobAux"/>


To reproduce the problem :
1) Fetch MasterJobAux  using the relationships

        MasterJob.getRelatedMasterJobAux();


2) delete/create some MasterJobAux

        MasterJob.removeFromRelatedMasterJobAux(toDelete);
        MasterJob.getObjectContext().deleteObject(toDelete);

3) Rollback

4) re-Fetch MasterJobAux  using the relationships

        MasterJob.getRelatedMasterJobAux();


I get TRANSIENT objects, you can look a the SQL log attached where there is some others details.


Thanks.

Laurent marchal.

Hi,

Sorry, you posted this earlier and looks like nobody replied yet.

So my question is : is this normal to get *TRANSIENT* objects from a relationship after a rollback ?

No, it is not normal. I just created a test case to reproduce it and things seem to be working ok:

PaintingInfo info = ctxt.newObject(PaintingInfo.class); info.setTextReview("XXX"); p1.setToPaintingInfo(info);

assertSame(info, p1.getToPaintingInfo()); ctxt.rollbackChanges(); assertNull(p1.getToPaintingInfo());

Does it look like the scenario that you have, or am I missing something?

Thanks, Andrus

On Sep 15, 2008, at 12:22 PM, Laurent Marchal wrote:

Hello again !

I have a strange thing happening in Cayenne 3.0M4 : I have two tables ARTIST and ARTIST_AUX where extended artist's properties are stored.

There is a relationship between ARTIST--->ARTIST_AUX where i checked "To Dep PK" since no ARTIST_AUX rows can exists without corresponding ARTIST.

I have also a addPrefetch(ARTIST_AUX) when i retrieve ARTISTs.

In my "artist editor" I create ARTIST_AUX rows at need and when an error occurs i do a rollback(). The strange thing is that when i refetch ARTISTS_AUX with the relationship, instead of getting only existing ARTISTS_AUX, i get also the ARTISTS_AUX created before the rollback() with the *TRANSIENT* state and no ObjectContext associated.

So my question is : is this normal to get *TRANSIENT* objects from a relationship after a rollback ?

Thanks Laurent Marchal.

### DISPLAY A MASTERJOB ###

--- will run 2 queries.
--- transaction started.
SELECT t0.SHORTNAME, t0.ALTMACH3ID, t0.ESTRUNTIME, t0.SKDID, t0.ALTMACH2ID, 
t0.PRIMMACHID, t0.JOBTYPE, t0.MACHGRPID, t0.DEPTID, t0.JOBGROUPID, 
t0.ALTMACH1ID, t0.JOBNAME, t0.ACCESSCDID FROM dbo.JMASTER t0 WHERE (t0.SKDID = 
?) AND (t0.JOBNAME = ?) [bind: 1->SKDID:5, 2->JOBNAME:'Backup de la base']
=== returned 1 row. - took 3 ms.
SELECT t0.SKDID, t0.JOBNAME, t0.JAVALUE, t0.JAFC, t0.JASEQNO FROM 
dbo.JMASTER_AUX t0 JOIN dbo.JMASTER t1 ON (t0.SKDID = t1.SKDID AND t0.JOBNAME = 
t1.JOBNAME) WHERE (t1.SKDID = ?) AND (t1.JOBNAME = ?) [bind: 1->SKDID:5, 
2->JOBNAME:'Backup de la base']
=== returned 12 rows. - took 3 ms.
+++ transaction committed.


### SAVE A MASTER JOB ON A READ ONLY DB TO FORCE ERROR ###

--- will run 1 query.
--- transaction started.
INSERT INTO dbo.JMASTER_AUX (JAFC, JASEQNO, JAVALUE, JOBNAME, SKDID) VALUES (?, 
?, ?, ?, ?)
[batch bind: 1->JAFC:3006, 2->JASEQNO:1, 3->JAVALUE:'AUX1', 4->JOBNAME:'Backup 
de la base', 5->SKDID:5]
[batch bind: 1->JAFC:3007, 2->JASEQNO:1, 3->JAVALUE:'AUX2', 4->JOBNAME:'Backup 
de la base', 5->SKDID:5]
*** error.
!STACK 0
java.sql.BatchUpdateException: Échec de la mise à jour de la base de données 
"OPCONXPS4_PROD" car celle-ci est en lecture seule.
        at 
net.sourceforge.jtds.jdbc.JtdsStatement.executeBatch(JtdsStatement.java:944)
        at 
org.apache.cayenne.access.jdbc.BatchAction.runAsBatch(BatchAction.java:133)
        at 
org.apache.cayenne.access.jdbc.BatchAction.performAction(BatchAction.java:80)


### RESAVE THE MASTER JOB ###

ERROR Transient OBJECT : {<no id>; transient; 
[relatedMasterJob=>{<ObjectId:MasterJob, JOBNAME=Backup de la base, SKDID=5>}; 
javalue=>AUX1; jaFieldCode=>3006; jaSequenceNumber=>1; scheduleId=>5; 
jobName=>Backup de la base]}
ERROR Transient OBJECT : {<no id>; transient; 
[relatedMasterJob=>{<ObjectId:MasterJob, JOBNAME=Backup de la base, SKDID=5>}; 
javalue=>AUX2; jaFieldCode=>3007; jaSequenceNumber=>1; scheduleId=>5; 
jobName=>Backup de la base]}

--- will run 1 query.
--- transaction started.
INSERT INTO dbo.JMASTER_AUX (JAFC, JASEQNO, JAVALUE, JOBNAME, SKDID) VALUES (?, 
?, ?, ?, ?)
[batch bind: 1->JAFC:3006, 2->JASEQNO:1, 3->JAVALUE:'AUX1', 4->JOBNAME:'Backup 
de la base', 5->SKDID:5]
[batch bind: 1->JAFC:3007, 2->JASEQNO:1, 3->JAVALUE:'AUX2', 4->JOBNAME:'Backup 
de la base', 5->SKDID:5]
*** error.
!STACK 0
java.sql.BatchUpdateException: Échec de la mise à jour de la base de données 
"OPCONXPS4_PROD" car celle-ci est en lecture seule.
        at 
net.sourceforge.jtds.jdbc.JtdsStatement.executeBatch(JtdsStatement.java:944)
        at 
org.apache.cayenne.access.jdbc.BatchAction.runAsBatch(BatchAction.java:133)
        at 
org.apache.cayenne.access.jdbc.BatchAction.performAction(BatchAction.java:80)

Reply via email to