I'm using castor-1.0M2 with Hibernate-3.1
Here is the top (bottom?) of the stack trace.
org.exolab.castor.mapping.loader.MappingLoader.getDescriptor Line 193
org.exolab.castor.xml.util.ClassDescriptorResolverImpl.resolve Line 248
org.exolab.castor.xml.Validator.validate Line 111
Werner Guttmann wrote:
Andrew,
Please see inline for comments ...
Werner
-----Original Message-----
From: Andrew Mason [mailto:[EMAIL PROTECTED]
Sent: Dienstag, 14. Februar 2006 13:46
To: [email protected]
Subject: [castor-user] Re: [SPAM] - [SPAM] - Re:
[castor-user] Castor marshalling Hibernate Pojos - Email
found in subject - Email found in subject - Email found in
subject - Email found in subject
Thanks for all your suggestions guys,
I think I've figured out what is going on here, and it does
seem to be linked to the fact that Hibernate is using CGLIB
enhancements for Classes that are lazily loaded.
During the Validate phase of the Marshalling, the method
MappingLoader.getDescriptor(Class type) is called, this uses
the Hashtable _clsDescs to find the ClassDescriptor which are
keyed by the pojo's classes.
However, when the marshaller gets the class of a lazily
loaded field (with it's CGLIB enhancements), it doesn't match
the classes within MappingLoader._clsDescs, so the Marshaller
treats the classes as not mapped, and introspects them.
Can you please point me to the exact location of the code described here
? I am sure a solution can be provided, though it is not going to be
easy .. ;-).
I don't know if this is the only place this is a problem, or
whether I'm going to encounter similar issues deeper within
the code - can anyone tell me?
No, I don't know either, as I am not that familiar with Castor XML as
with the JDO side of things. But maybe somebody else can step in and
answer that question.
I figure it must be possible to fix this problem, and as the
alternative is to drop Castor XML from the project I'll have a go.
Well, well ... dropping something that works otherwise does not look
like a viable option to me .. ;-). Let's see what we can come up with.
Unless there is some other way of geting around it?
Any ideas?
Thanks
Andrew
Werner Guttmann wrote:
Stephen,
we'd be more than happy to provide you with some help when it comes
down to your personal learning experience. What do you need ?
To, for example, model a 1:M relation from A to B, in A
you'll need a
property named 'bs' of type e.g. List, and in the mapping
file a field
mapping similar to
<field name="bs" type="some.domain.B" collection="arraylist">
<sql many-key=" ..." />
</field>
And in terms of the SQL statements to create A and B, one
could use the
following statements as a starting point:
create table domain_a (
id int not null PRIMARY KEY,
name varchar(20)
);
create table domain_B 8
id int not null PRIMARY KEY,
descr varchar(20),
a_id int
);
I hope this keeps you going ... ;-).
Werner
Stephen Bash wrote:
Well gentlemen, since I've wanted to learn more about the JDO world
for a while now, I took this as a chance to read up more on Castor
JDO. And honestly, most of it makes sense though I have
very little
experience with O/R mapping. Unfortunately, when it comes
to actually
creating the database schema or correctly modeling the 1:m
relations,
I'm out of my league, so I'm probably going to have to
leave this one
for someone else.
Thanks,
Stephen
On 2/13/06, Ralf Joachim <[EMAIL PROTECTED]> wrote:
Hi Andrew, Hi Stephen,
according to my knowledge hibernate returns cglib-proxies
instead of
the original ones as they havily us lazy loading of data from
database. In the past a few users had problems with the
constelation
castor xml together with hibernate according to this cglib-proxies.
Just in case you are not aware of it
Ralf
Stephen Bash schrieb:
Andrew-
So I tried to recreate your problem with a simpler set of classes:
public class ParentFoo {
protected int parentId;
protected Set children;
public int getParentId() { return parentId; }
public void setParentId( int parentId ) { this.parentId =
parentId; }
public Set getChildren() { return children; }
public void setChildren( Set children ) {
this.children = children; }
}
public class ChildFoo {
protected int childId;
protected Set parents;
public int getChildId() { return childId; }
public void setChildId( int childId ) { this.childId =
childId; }
public Set getParents() { return parents; }
public void setParents( Set parents ) { this.parents =
parents; }
public String toString() { return( String.valueOf(
childId ) ); }
}
And the following mapping file:
<mapping>
<class name="ParentFoo">
<map-to xml="parent-foo" />
<field name="parentId" type="integer">
<bind-xml name="id" node="attribute" />
</field>
<field name="children" collection="set" type="ChildFoo">
<bind-xml name="child" />
</field>
</class>
<class name="ChildFoo">
<map-to xml="child-foo" />
<field name="childId" type="integer">
<bind-xml name="id" node="attribute" />
</field>
<!--
<field name="parents" collection="set"
type="castor.mason.one.ParentFoo">
<bind-xml name="parent" />
</field>
-->
</class>
</mapping>
I've attempted to recreate the 1:m m:1 relationship you had. You
can see in my mapping file I have the connection between the
children and the parents commented out. I then created a
series of
parents and children, mixing and matching them. Using
this mapping
file as is to marshal my first parent object I get:
<parent-foo id="1">
<child id="5"/>
<child id="4"/>
</parent-foo>
If I uncomment the child->parent relationship, I get:
<parent-foo id="1">
<child id="5">
<parent id="2">
<child id="6">
<parent id="3"/>
</child>
<child id="4"/>
</parent>
</child>
<child id="4">
<parent id="2">
<child id="6">
<parent id="3"/>
</child>
<child id="5"/>
</parent>
</child>
</parent-foo>
I'm somewhat surprised to find that I'm not getting the deep
recursion you mention. I tested this with Castor 0.9.9
and 1.0M2.
What version of Castor are you running? If you can run
this example
on your system and agree or disagree with the output,
that would also be helpful.
Do you see anything grossly different between your setup
and mine?
I don't have the intermediate classes, so that might
change things,
but I wanted to start simple.
Let me know your thoughts on this example and its
comparison to your
code. I can't directly answer your question because from
what I can
tell, you're doing what I'm doing...
Stephen
On 2/13/06, Andrew Mason <[EMAIL PROTECTED]> wrote:
OK,
Here is the castor mapping file:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapping PUBLIC
"-//EXOLAB/Castor Object Mapping DTD Version 1.0//EN"
"http://castor.org/mapping.dtd">
<mapping> <class name="uk.gov.forestry.harpps.model.Species"
auto-complete="false"> <map-to xml="species"/> <field
name="scientificName"> <bind-xml name="scientific-name"
node="attribute"/> </field> <field name="protections"
collection="set"
type="uk.gov.forestry.harpps.model.Protection">
</field>
</class>
<class name="uk.gov.forestry.harpps.model.Protection"
auto-complete="false">
<map-to xml="protection"/>
<field name="lookupProtection"
type="uk.gov.forestry.harpps.model.LookupProtection">
<bind-xml name="lookup-protection" node="element"/> </field>
</class>
<class name="uk.gov.forestry.harpps.model.LookupProtection"
auto-complete="false">
<map-to xml="protection-lookup"/>
<field name="protectionName">
<bind-xml name="protection-name" node="attribute"/>
</field> <field
name="lookupProtectionType"
type="uk.gov.forestry.harpps.model.LookupProtectionType">
<bind-xml name="protection-type" node="element"/>
</field> </class>
<class name="uk.gov.forestry.harpps.model.LookupProtectionType"
auto-complete="false">
<map-to xml="protection-type"/>
<field name="protectionTypeId">
<bind-xml name="protection-type-id" node="attribute"/> </field>
</class> </mapping>
A Species has a Hashset of Protection objects. It also has many
other Objects associated with it in a similar way, but I'm not
interested in generating the XML for those (yet).
A Protection has a LookupProtection object, and a
protectionName String.
A LookupProtection object has a LookupProtectionType object.
A LookupProtectionType has a protectionTypeId (long)
Below is the java code of the LookupProtectionType
class, you will
see it has a relationship back to the LookupProtection
object, but
I don't want to show this within the XML. Most of the
Objects also
have similar
2 way relationships.
public class LookupProtectionType implements
java.io.Serializable
{
// Fields
private long protectionTypeId;
private String protectionType;
private Set lookupProtections = new HashSet(0);
// Constructors
/** default constructor */
public LookupProtectionType() {
}
/** minimal constructor */
public LookupProtectionType(long protectionTypeId) {
this.protectionTypeId = protectionTypeId;
}
/** full constructor */
public LookupProtectionType(long protectionTypeId, String
protectionType, Set lookupProtections) {
this.protectionTypeId = protectionTypeId;
this.protectionType = protectionType;
this.lookupProtections = lookupProtections;
}
// Property accessors
public long getProtectionTypeId() {
return this.protectionTypeId;
}
public void setProtectionTypeId(long protectionTypeId) {
this.protectionTypeId = protectionTypeId;
}
public String getProtectionType() {
return this.protectionType;
}
public void setProtectionType(String protectionType) {
this.protectionType = protectionType;
}
public Set getLookupProtections() {
return this.lookupProtections;
}
public void setLookupProtections(Set lookupProtections) {
this.lookupProtections = lookupProtections;
}
}
Within the Hibernate mapping I made all the
relationships Lazy, so
they should only load when their get method is called.
When I test the marshalling, I can see all the
Non-mapped objects
being queried from the database.
I have tried mapping all the fields and setting them as
Trasient,
but that seemed to have no effect.
Werner Guttmann wrote:
Andrew,
Can you please show us the relevant mapping file
section you are
using to 'disable' some of the relations ?
Thanks
Werner
-----Original Message-----
From: Andrew Mason [mailto:[EMAIL PROTECTED]
Sent: Montag, 13. Februar 2006 11:56
To: [email protected]
Subject: [castor-user] Castor marshalling Hibernate Pojos
Hello,
I apologise if this topic has been covered before - if so a
pointer to the relevent posts will be appreciated.
I am using Hibernate as my object persistence layer
(sorry but I
can't use Castor JDO due to political reasons).
I wish to use Castor XML to marshall the pojos into
xml documents.
Many of the objects have relationships with objects that are
required from a database perspective, but are not
required within
the XML.
For example
Species has a one-to-many relationship with Predator.
Predator has a one-to-many relationship with Species.
When I marshal a Species object I want to include it's
predators,
however, I do not want to include all the Species the predator
preys upon within the Species XML document.
I assumed that by writing a mapping document for
Predator, that
did not include rerlationship with Species, Castor would not
bother calling the getPreySpecies method.
What I am finding is that despite the mapping not
including this
relationship, the method is still being called, causing more
species to be instantiated, thus causing more predators to be
instantiated and so on until my machine runs out of memory!
Is there any way of ensuring that the Marshaller pays strict
attention to the Map, and doesn't call methods that
are not defined?
Thanks
--
*************************************************
Andrew Mason
Environ-IT Ltd.
Tel.: 01899 880200
Mob.: 07919 967494
E-mail: [EMAIL PROTECTED]
*************************************************
-------------------------------------------------
If you wish to unsubscribe from this list, please send
an empty
message to the following address:
[EMAIL PROTECTED]
-------------------------------------------------
-------------------------------------------------
If you wish to unsubscribe from this list, please send an empty
message to the following address:
[EMAIL PROTECTED]
-------------------------------------------------
--
*************************************************
Andrew Mason
Environ-IT Ltd.
Tel.: 01899 880200
Mob.: 07919 967494
E-mail: [EMAIL PROTECTED]
*************************************************
-------------------------------------------------
If you wish to unsubscribe from this list, please send an empty
message to the following address:
[EMAIL PROTECTED]
-------------------------------------------------
-------------------------------------------------
If you wish to unsubscribe from this list, please send an empty
message to the following address:
[EMAIL PROTECTED]
-------------------------------------------------
-------------------------------------------------
If you wish to unsubscribe from this list, please send an
empty message
to the following address:
[EMAIL PROTECTED]
-------------------------------------------------
--
*************************************************
Andrew Mason
Environ-IT Ltd.
Tel.: 01899 880200
Mob.: 07919 967494
E-mail: [EMAIL PROTECTED]
*************************************************
-------------------------------------------------
If you wish to unsubscribe from this list, please
send an empty message to the following address:
[EMAIL PROTECTED]
-------------------------------------------------
-------------------------------------------------
If you wish to unsubscribe from this list, please
send an empty message to the following address:
[EMAIL PROTECTED]
-------------------------------------------------
--
*************************************************
Andrew Mason
Environ-IT Ltd.
Tel.: 01899 880200
Mob.: 07919 967494
E-mail: [EMAIL PROTECTED]
*************************************************
-------------------------------------------------
If you wish to unsubscribe from this list, please
send an empty message to the following address:
[EMAIL PROTECTED]
-------------------------------------------------