Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF "Technology" (Ecore Tools, EMFatic, etc)  » [ Teneo ] SDO class name problem
[ Teneo ] SDO class name problem [message #89071] Wed, 11 July 2007 19:09 Go to next message
Jason Henriksen is currently offline Jason HenriksenFriend
Messages: 231
Registered: July 2009
Senior Member
Hi Again,

So having sorted out how to make a Teno generated HBM get used, I found my
next difficulty. I'm using the genmodel to create SDO objects and when Teno
reads the sdo objects to build the mapping everything works great and I get
hbm that looks like this:

<class name="com.vsp.consumer.impl.ConsumerImpl"
entity-name="Consumer"
abstract="false" lazy="false" discriminator-value="Consumer"
table="`cmr3601t`">
<meta attribute="eclassName">Consumer</meta>

The key thing here is taht the name="com.vsp.consumer.impl.ConsumerImpl"

<class name="org.eclipse.emf.ecore.impl.DynamicEObjectImpl"
entity-name="Consumer"
abstract="false" lazy="false" discriminator-value="Consumer"
table="`cmr3601t`">
<meta attribute="eclassName">Consumer</meta>

This blows up when I try to use this hbm because the data store
initialization expects DynamicEObjectImpl to have getters and setters for
all my fields in the same way that ConsumerImpl does.

I use the "Set SDO defaults" on the gen model before I generate the model
code since I have to have pojos for my clients to interact with. Is there
some similar configuration that I need to set for Teneo to put the correct
names in place?

If there's a feature enhancement to be done here, let me know. I'm looking
at the code as well, but I thought I'd ask since the solution isn't jumping
out at me.

I've gotten my local teneo version to put <comment> tags into the hbm from
the ecore. Once I can fix this and prove that that my objects will work,
I'll be about ready to submit that to you as well.

Jason Henriksen
Re: [ Teneo ] SDO class name problem [message #89086 is a reply to message #89071] Wed, 11 July 2007 19:28 Go to previous messageGo to next message
Martin Taal is currently offline Martin TaalFriend
Messages: 5468
Registered: July 2009
Senior Member
Hi Jason,
I am not sure how you got the DynamicEObjectImpl in the hbm file.
This happens in case of a dynamic emf model (without generated java code). This is a current bug:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=193052
I have solved this in cvs. If it is this bug then to work around this for now you can remove this
from the hbm:
name="org.eclipse.emf.ecore.impl.DynamicEObjectImpl"
(a global search and replace will work)

Still, I don't really understand why it does not pick up the CustomerImpl class.
You can also programmatically create the hbm file (see the HbHelper class) this is safer from a
classloading point of view and allows you to pass options when generating the hbm.

gr. Martin

Jason Henriksen wrote:
> Hi Again,
>
> So having sorted out how to make a Teno generated HBM get used, I found my
> next difficulty. I'm using the genmodel to create SDO objects and when Teno
> reads the sdo objects to build the mapping everything works great and I get
> hbm that looks like this:
>
> <class name="com.vsp.consumer.impl.ConsumerImpl"
> entity-name="Consumer"
> abstract="false" lazy="false" discriminator-value="Consumer"
> table="`cmr3601t`">
> <meta attribute="eclassName">Consumer</meta>
>
> The key thing here is taht the name="com.vsp.consumer.impl.ConsumerImpl"
>
> <class name="org.eclipse.emf.ecore.impl.DynamicEObjectImpl"
> entity-name="Consumer"
> abstract="false" lazy="false" discriminator-value="Consumer"
> table="`cmr3601t`">
> <meta attribute="eclassName">Consumer</meta>
>
> This blows up when I try to use this hbm because the data store
> initialization expects DynamicEObjectImpl to have getters and setters for
> all my fields in the same way that ConsumerImpl does.
>
> I use the "Set SDO defaults" on the gen model before I generate the model
> code since I have to have pojos for my clients to interact with. Is there
> some similar configuration that I need to set for Teneo to put the correct
> names in place?
>
> If there's a feature enhancement to be done here, let me know. I'm looking
> at the code as well, but I thought I'd ask since the solution isn't jumping
> out at me.
>
> I've gotten my local teneo version to put <comment> tags into the hbm from
> the ecore. Once I can fix this and prove that that my objects will work,
> I'll be about ready to submit that to you as well.
>
> Jason Henriksen
>
>


--

With Regards, Martin Taal

Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
Re: [ Teneo ] SDO class name problem [message #89544 is a reply to message #89086] Thu, 12 July 2007 20:20 Go to previous messageGo to next message
Jason Henriksen is currently offline Jason HenriksenFriend
Messages: 231
Registered: July 2009
Senior Member
Hi Martin,

> I am not sure how you got the DynamicEObjectImpl in the hbm file.
> This happens in case of a dynamic emf model (without generated java code).
This is a current bug:
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=193052

For me, the class name information is not present because I run teneo with
only the ecore available by invoding the main in GenerateHBM. I tried
putting the SDO classes into the class path but it wasn't enough and no good
naming was found.

> I have solved this in cvs. If it is this bug then to work around this for
now you can remove this
> from the hbm:
> name="org.eclipse.emf.ecore.impl.DynamicEObjectImpl"

Applying the fix from CVS also didn't work out completely. It helped in
that the name attribute was not present until runtime and so the mappings
would generate but two other problems came up:
- Enumeration types still failed because the name wasn't present and so it
couldn't find the correct values
- Relationships didn't work because the keys information couldn't be found.

So I used teneo at run time, captured the output HBM and kept hacking at the
ecore-only generation method until I could get the same result. The main
problem was that there was no way to get the java package because that
information doesn't get put in the .ecore file.

I control the output package for the java files by using ecore:package like
this:

<xsd:schema targetNamespace="http://vsp.com/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:vsp="http://vsp.com/"
xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
ecore:package="com.vsp.consumer">

But ecore:package only goes to the genmodel, not to the ecore file. Luckily
I discovered nsPrefix:

<xsd:schema targetNamespace="http://vsp.com/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:vsp="http://vsp.com/"
xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
ecore:package="com.vsp.consumer"
ecore:nsPrefix="com.vsp.consumer">

By putting this into the XSD, I can get a hold of it in the ecore. From
there I generate all the names in the same way that the SDO code generator
will and everything comes out perfectly. The names are specified correctly,
the keys and the enums all work great.

Basically, I keep the current fix, but when I'm generating the xml for the
entity I add

target.addAttribute("name",
entity.getAnnotatedEClass().getEPackage().getNsPrefix()+".impl. "+
entity.getEntity().getName()+"Impl");

I'd like to make another property that will control wether or not to use the
nsPrefix like that. It seems like this is what the nsPrefix attribute was
put in there for and as fas as I can tell teneo isn't really using it any
differently in the few places that it uses it at all. I was thinking about
a property like USE_NS_PREFIX_FOR_JAVA_NAME_GENERATION to control wether
this gets used or not, but whatever you like is good for me.

Let me know what you think, and I'll make another submission for this. I'll
keep three submissions seperate so you can review them individually. I've
got Comments, UseSpecificHBMFile and now nsPrefixForPackage as the three
things I'm about ready to send your way.

Talk to you soon,

Jason Henriksen
Re: [ Teneo ] SDO class name problem [message #89559 is a reply to message #89544] Thu, 12 July 2007 20:32 Go to previous messageGo to next message
Martin Taal is currently offline Martin TaalFriend
Messages: 5468
Registered: July 2009
Senior Member
Hi Jason,
I am not sure about using the nsprefix. Teneo/Hibernate should also work with dynamic emf (so no
generated java code). What goes exactly wrong in these two cases?
> - Enumeration types still failed because the name wasn't present and so it
> couldn't find the correct values
> - Relationships didn't work because the keys information couldn't be found.

How does the hbm look like in this case?

gr. Martin

Jason Henriksen wrote:
> Hi Martin,
>
>> I am not sure how you got the DynamicEObjectImpl in the hbm file.
>> This happens in case of a dynamic emf model (without generated java code).
> This is a current bug:
>> https://bugs.eclipse.org/bugs/show_bug.cgi?id=193052
>
> For me, the class name information is not present because I run teneo with
> only the ecore available by invoding the main in GenerateHBM. I tried
> putting the SDO classes into the class path but it wasn't enough and no good
> naming was found.
>
>> I have solved this in cvs. If it is this bug then to work around this for
> now you can remove this
>> from the hbm:
>> name="org.eclipse.emf.ecore.impl.DynamicEObjectImpl"
>
> Applying the fix from CVS also didn't work out completely. It helped in
> that the name attribute was not present until runtime and so the mappings
> would generate but two other problems came up:
> - Enumeration types still failed because the name wasn't present and so it
> couldn't find the correct values
> - Relationships didn't work because the keys information couldn't be found.
>
> So I used teneo at run time, captured the output HBM and kept hacking at the
> ecore-only generation method until I could get the same result. The main
> problem was that there was no way to get the java package because that
> information doesn't get put in the .ecore file.
>
> I control the output package for the java files by using ecore:package like
> this:
>
> <xsd:schema targetNamespace="http://vsp.com/"
> xmlns:xsd="http://www.w3.org/2001/XMLSchema"
> xmlns:vsp="http://vsp.com/"
> xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
> ecore:package="com.vsp.consumer">
>
> But ecore:package only goes to the genmodel, not to the ecore file. Luckily
> I discovered nsPrefix:
>
> <xsd:schema targetNamespace="http://vsp.com/"
> xmlns:xsd="http://www.w3.org/2001/XMLSchema"
> xmlns:vsp="http://vsp.com/"
> xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
> ecore:package="com.vsp.consumer"
> ecore:nsPrefix="com.vsp.consumer">
>
> By putting this into the XSD, I can get a hold of it in the ecore. From
> there I generate all the names in the same way that the SDO code generator
> will and everything comes out perfectly. The names are specified correctly,
> the keys and the enums all work great.
>
> Basically, I keep the current fix, but when I'm generating the xml for the
> entity I add
>
> target.addAttribute("name",
> entity.getAnnotatedEClass().getEPackage().getNsPrefix()+".impl. "+
> entity.getEntity().getName()+"Impl");
>
> I'd like to make another property that will control wether or not to use the
> nsPrefix like that. It seems like this is what the nsPrefix attribute was
> put in there for and as fas as I can tell teneo isn't really using it any
> differently in the few places that it uses it at all. I was thinking about
> a property like USE_NS_PREFIX_FOR_JAVA_NAME_GENERATION to control wether
> this gets used or not, but whatever you like is good for me.
>
> Let me know what you think, and I'll make another submission for this. I'll
> keep three submissions seperate so you can review them individually. I've
> got Comments, UseSpecificHBMFile and now nsPrefixForPackage as the three
> things I'm about ready to send your way.
>
> Talk to you soon,
>
> Jason Henriksen
>
>
>
>


--

With Regards, Martin Taal

Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
Re: [ Teneo ] SDO class name problem [message #89649 is a reply to message #89559] Thu, 12 July 2007 23:19 Go to previous messageGo to next message
Jason Henriksen is currently offline Jason HenriksenFriend
Messages: 231
Registered: July 2009
Senior Member
This is a multi-part message in MIME format.

------=_NextPart_000_00E9_01C7C4A0.7B3D87F0
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable


I agree that nsPrefix isn't the prettiest thing in the world, but =
without the java package I run into these two problems:

=3D=3D PROBLEM 1:
When I first applied the fix in CVS I started seeing the enumerated =
types fail. I got this hbm
<type =
name=3D"org.eclipse.emf.teneo.hibernate.mapping.DynamicENumUserType ">
<param name=3D"eclassifier">RelationshipCodeType</param>
<param name=3D"epackage">http://vsp.com/</param>
</type>
Instead of the runtime generated hbm which looks like this:
<type =
name=3D"org.eclipse.emf.teneo.hibernate.mapping.ENumUserType ">
<param =
name=3D"enumClass">com.vsp.consumer.RelationshipCodeType</param >
</type>

The basic problem is that it tries cast DynamicENumUserType to the =
specific enumation type that I've defined, but that it doesn't know =
about from the ecore. Here's the exception:

java.lang.ClassCastException: com.vsp.consumer.GenderCodeType
Hibernate: /* insert Consumer */ insert into "cmr3601t" ("isd_lock_ct", =
"consumer_id", "name_prefix", "first_name", "middle_initial", =
"last_name", "name_suffix", "ssn", "date_of_birth", "gender_cd", =
"marital_status_cd", "citizenship_ind", "disability_ind", =
"ethnicity_cd", "other_id", "other_id_type_cd", "personal_info", =
"place_of_birth", "prefer_comm_method", "isd_lupd_id", econtainer_class, =
e_container, e_container_featureid, "dtype", "consumer_sk") values (?, =
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, =
'Consumer', ?)
at =
org.eclipse.emf.teneo.hibernate.mapping.DynamicENumUserType. nullSafeSet(D=
ynamicENumUserType.java:137)
at org.hibernate.type.CustomType.nullSafeSet(CustomType.java:14 6)
at =
org.hibernate.persister.entity.AbstractEntityPersister.dehyd rate(Abstract=
EntityPersister.java:1997)
at =
org.hibernate.persister.entity.AbstractEntityPersister.inser t(AbstractEnt=
ityPersister.java:2243)

I solve this by altering AbstractMapper like this:

private void handleEnumType(PAnnotatedEAttribute paAttribute, Element =
propElement) {
final Enumerated enumerated =3D paAttribute.getEnumerated();
assert (enumerated !=3D null);
final EAttribute eattr =3D paAttribute.getAnnotatedEAttribute();
final EClassifier eclassifier =3D eattr.getEType();
if (!getHbmContext().isGeneratedByEMF()
&& getHbmContext().getInstanceClass(eclassifier) !=3D null) {
final Class<?> instanceClass =3D =
getHbmContext().getInstanceClass(eclassifier);
propElement.addElement("type").addAttribute("name", =
getEnumUserType(enumerated))
.addElement("param").addAttribute("name", =
HbMapperConstants.ENUM_CLASS_PARAM)
.addText(instanceClass.getName());
} else if (getHbmContext().isGeneratedByEMF() && =
eclassifier.getInstanceClass() !=3D null) {
propElement.addElement("type").addAttribute("name", =
getEnumUserType(enumerated))
.addElement("param").addAttribute("name", =
HbMapperConstants.ENUM_CLASS_PARAM)
.addText(eclassifier.getInstanceClass().getName());
}=20
//--- JJH
else if (true) { // would be a property
=20
// brute force this to behave by letting the user specify what =
package should be used.
// If this is not enabled, enumerations are treated as the wrong =
type.
// This is ONLY needed if you are generating .hbm directly from =
..ecore without using annotated class files. =20
String packageName =3D eclassifier.getEPackage().getNsPrefix();
propElement.addElement("type").addAttribute("name", =
getEnumUserType(enumerated))
.addElement("param").addAttribute("name", =
HbMapperConstants.ENUM_CLASS_PARAM)
.addText(packageName+"."+eclassifier.getName());
}
//--- JJH
else { // must be emf dynamic
final Element typeElement =3D
propElement.addElement("type").addAttribute("name",
hbDynamicEnumType(enumerated));
typeElement.addElement("param").addAttribute("name",
HbMapperConstants.ECLASSIFIER_PARAM).addText(eclassifier.get Name());
typeElement.addElement("param").addAttribute("name", =
HbMapperConstants.EPACKAGE_PARAM)
.addText(eclassifier.getEPackage().getNsURI());
}

}

=3D=3D PROBLEM 2:
So if I fix the CCE above with that bit of hardcoding and still let the =
output hbm look like this:
<class entity-name=3D"Address" abstract=3D"false" lazy=3D"false" =
discriminator-value=3D"Address" table=3D"`cmr3605t`">
instead of how it should look as in this example:
<class name=3D"com.vsp.consumer.impl.AddressImpl" =
entity-name=3D"Address" abstract=3D"false" lazy=3D"false" =
discriminator-value=3D"Address" table=3D"`cmr3605t`">

I end up with this mess when I relate the objects (-530 means invalid =
foreign key value. Basically, it doesn't know how to map the =
relationships and puts a bad value into the jdbc statement):
------------------------
2007/07/12 15:38:32:551 PDT [DEBUG] SQL - /* insert RelatedConsumer */ =
insert into "cmr3602t" (e_id, "isd_lock_ct", "consumer_sk", =
"related_cmr_sk", "cmr_relate_cd", "relate_start_dt", =
"relate_end_dt", "isd_lupd_id", econtainer_class, e_container, =
e_container_featureid, "dtype") values (default, ?, ?, ?, ?, ?, ?, ?, ?, =
?, ?, 'RelatedConsumer')
2007/07/12 15:38:32:566 PDT [DEBUG] AbstractBatcher - about to close =
PreparedStatement (open PreparedStatements: 1, globally: 1)
2007/07/12 15:38:32:582 PDT [DEBUG] JDBCExceptionReporter - could not =
insert: [RelatedConsumer] [/* insert RelatedConsumer */ insert into =
"cmr3602t" (e_id, "isd_lock_ct", "consumer_sk", "related_cmr_sk", =
"cmr_relate_cd", "relate_start_dt", "relate_end_dt", "isd_lupd_id", =
econtainer_class, e_container, e_container_featureid, "dtype") values =
(default, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'RelatedConsumer')] =
<com.ibm.db2.jcc.b.SqlException: DB2 SQL error: SQLCODE: -530, SQLSTATE: =
23503, SQLERRMC: =
DB2ADMIN.cmr3602t.FK778C01274EE35F59>com.ibm.db2.jcc.b.SqlException: DB2 =
SQL error: SQLCODE: -530, SQLSTATE: 23503, SQLERRMC: =
DB2ADMIN.cmr3602t.FK778C01274EE35F59
2007/07/12 15:38:32:582 PDT [WARN] JDBCExceptionReporter - SQL Error: =
-530, SQLState: 23503
2007/07/12 15:38:32:582 PDT [ERROR] JDBCExceptionReporter - DB2 SQL =
error: SQLCODE: -530, SQLSTATE: 23503, SQLERRMC: =
DB2ADMIN.cmr3602t.FK778C01274EE35F59
org.hibernate.exception.ConstraintViolationException: could not insert: =
[RelatedConsumer]
at =
org.hibernate.exception.SQLStateConverter.convert(SQLStateCo nverter.java:=
71)
at =
org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExce ptionHelper.j=
ava:43)
at =
org.hibernate.id.insert.AbstractReturningDelegate.performIns ert(AbstractR=
eturningDelegate.java:40)
at =
org.hibernate.persister.entity.AbstractEntityPersister.inser t(AbstractEnt=
ityPersister.java:2158)
at =
org.hibernate.persister.entity.AbstractEntityPersister.inser t(AbstractEnt=
ityPersister.java:2638)
at =
org.hibernate.action.EntityIdentityInsertAction.execute(Enti tyIdentityIns=
ertAction.java:48)
-----------------------

I solve this with this bit of code in EntityMapper.java:

private Element createEntity(PAnnotatedEClass entity,
InheritanceType inhStrategy, =
PAnnotatedEClass superEntity,
DiscriminatorValue dValue, =
Table table) {

...
final Element target;

final String entityName =3D getHbmContext().getEntityName(eclass);
final String isAbstractStr =3D eclass.isAbstract() ? "true" : "false";
if (entity.isOnlyMapAsEntity()) {
target =3D getHbmContext().getCurrent().addElement(hbClassName);
=20
if (hasCompositeID(entity)) { // only for this specific case
String foo =3D =
hbmContext.getInstanceClassName(entity.getAnnotatedEClass()) ;
target.addAttribute("name", foo);
}
//--- hard code fix for missing class files.
else{ =20
//--- JJH
target.addAttribute("name", =
entity.getAnnotatedEClass().getEPackage().getNsPrefix()+".impl. "+entity.g=
etEntity().getName()+"Impl");
//--- JJH
}
...

I probably need to fix the name attribute in more places than this, but =
doing it here makes all my code work.

=3D=3D OTHER POSSIBLE SOLUTIONS:

I thought about putting the package prefix that I need into a property, =
but that's no fun because I'd have to change it every time I ran another =
ecore file through. Ideally there should be something in the ecore that =
would hold the package name, but it's not there. And since I can =
specify any random value for ecore:package in the xsd I really need to =
have the right string in order for things to match up at runtime. =20

I considered adding annotation to the basic schema level, but the =
annotations only come through on the actual entity objects. I didn't =
want to re-specify the package on every entity because that seems even =
more redundant than using nsPrefix.

I also found nsPrefix being used in a somewhat similar way in the =
existing teneo code here:

HibernateFeatureMapEntry:
/** Code copied from FeatureMapUtil.EntryImpl */
public String toString() {
String prefix =3D =
eStructuralFeature.getEContainingClass().getEPackage().getNs Prefix();
eStructuralFeature.getName();
return (prefix !=3D null && prefix.length() !=3D 0 ? prefix + ":" + =
eStructuralFeature.getName()
: eStructuralFeature.getName())
+ "=3D" + getValue();
}

and in QualifyingEClassNameStrategy

public String toUniqueName(EClass eClass) {
if (eClass =3D=3D null) {
throw new IllegalArgumentException("EClass cannot be null.");
}
if (eClass =3D=3D EOBJECT_ECLASS) {
return EOBJECT_ECLASS_NAME;
}
String nsPrefix =3D eClass.getEPackage().getNsPrefix();
if (nsPrefix =3D=3D null) {
nsPrefix =3D eClass.getEPackage().getName();
}
return nsPrefix + "." + eClass.getName();
}

Not quite the same, but close enough that it seemed like a reasonable =
fit. =20
I'm completely open to any other solution you might suggest.

Remember that both of these problems do not exist if you're letting =
teneo run when the classes are available. Its only when you run =
GenerateHBM against an ecore with no other input and then force teneo to =
use that HBM that you run into these troubles.

Talk to you soon,

Jason=20




------=_NextPart_000_00E9_01C7C4A0.7B3D87F0
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=3DContent-Type content=3D"text/html; =
charset=3Diso-8859-1">
<META content=3D"MSHTML 6.00.2800.1561" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=3D#ffffff background=3D""><FONT face=3DArial =
size=3D2></FONT><FONT=20
face=3DArial size=3D2></FONT>
<DIV><FONT face=3DArial size=3D2></FONT><BR><FONT face=3DArial =
size=3D2>I agree that=20
nsPrefix isn't the prettiest thing in the world, but without the java =
package I=20
run into these two problems:<BR><BR>=3D=3D PROBLEM 1:<BR>When I first =
applied the=20
fix in CVS I started seeing the enumerated types fail.&nbsp; I got this=20
hbm</FONT></DIV>
<DIV><FONT face=3DArial =
size=3D2> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;=20
&lt;type=20
name=3D"org.eclipse.emf.teneo.hibernate.mapping.DynamicENumUserType "&gt;<=
BR>&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &lt;param=20
name=3D"eclassifier"&gt;RelationshipCodeType&lt;/param&gt; <BR>&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp ;&nbsp;&nbsp;&nbsp;=20
&lt;param =
name=3D"epackage"&gt;http://vsp.com/&lt;/param&gt;<BR>&nbsp;&nbsp;&nbsp; =

&nbsp;&nbsp;&nbsp;&nbsp; &lt;/type&gt;<BR></FONT><FONT face=3DArial =
size=3D2>Instead=20
of the runtime generated hbm which looks like this:</FONT></DIV>
<DIV><FONT face=3DArial =
size=3D2> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;=20
&lt;type=20
name=3D"org.eclipse.emf.teneo.hibernate.mapping.ENumUserType "&gt;<BR>&nbs=
p;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&lt;param=20
name=3D"enumClass" &gt;com.vsp.consumer.RelationshipCodeType&lt;/param& amp;gt;=
<BR>&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp;&nbsp; &lt;/type&gt;<BR></FONT><FONT face=3DArial =
size=3D2><BR>The=20
basic problem is that it tries cast DynamicENumUserType to the specific=20
enumation type that I've defined, but that it doesn't know about from =
the=20
ecore.&nbsp; Here's the exception:</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>java.lang.ClassCastException:=20
com.vsp.consumer.GenderCodeType<BR>Hibernate: /* insert Consumer */ =
insert into=20
"cmr3601t" ("isd_lock_ct", "consumer_id", "name_prefix", "first_name",=20
"middle_initial", "last_name", "name_suffix", "ssn", "date_of_birth",=20
"gender_cd", "marital_status_cd", "citizenship_ind", "disability_ind",=20
"ethnicity_cd", "other_id", "other_id_type_cd", "personal_info",=20
"place_of_birth", "prefer_comm_method", "isd_lupd_id", econtainer_class, =

e_container, e_container_featureid, "dtype", "consumer_sk") values (?, =
?, ?, ?,=20
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'Consumer',=20
?)<BR>&nbsp;&nbsp;&nbsp; &nbsp;at=20
org.eclipse.emf.teneo.hibernate.mapping.DynamicENumUserType. nullSafeSet(D=
ynamicENumUserType.java:137)<BR>&nbsp;&nbsp;&nbsp;=20
&nbsp;at=20
org.hibernate.type.CustomType.nullSafeSet(CustomType.java:14 6) <BR>&nbsp;&=
nbsp;&nbsp;=20
&nbsp;at=20
org.hibernate.persister.entity.AbstractEntityPersister.dehyd rate(Abstract=
EntityPersister.java:1997)<BR>&nbsp;&nbsp;&nbsp;=20
&nbsp;at=20
org.hibernate.persister.entity.AbstractEntityPersister.inser t(AbstractEnt=
ityPersister.java:2243)<BR></DIV></FONT>
<DIV><FONT face=3DArial size=3D2>I solve this by altering AbstractMapper =
like=20
this:</FONT></DIV>
<DIV><FONT face=3DArial size=3D2><BR><FONT face=3DCourier>&nbsp;private =
void=20
handleEnumType(PAnnotatedEAttribute paAttribute, Element propElement)=20
{<BR>&nbsp;&nbsp;final Enumerated enumerated =3D=20
paAttribute.getEnumerated();<BR>&nbsp;&nbsp;assert (enumerated !=3D=20
null);<BR>&nbsp;&nbsp;final EAttribute eattr =3D=20
paAttribute.getAnnotatedEAttribute();<BR>&nbsp;&nbsp;final EClassifier=20
eclassifier =3D eattr.getEType();<BR>&nbsp;&nbsp;if=20
(!getHbmContext().isGeneratedByEMF()<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&amp;&amp;=20
getHbmContext().getInstanceClass(eclassifier) !=3D null) =
{<BR>&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp;final Class&lt;?&gt; instanceClass =3D=20
getHbmContext().getInstanceClass(eclassifier);<BR>&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp;propElement.addElement("type").addAttribute( "name",=20
getEnumUserType(enumerated))<BR>&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp;&nbsp;.addElement("param").addAttribute( "name",=20
HbMapperConstants.ENUM_CLASS_PARAM)<BR>&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp;&nbsp;.addText(instanceCla ss.getName()); <BR>&nbsp;&nbsp=
;} else=20
if (getHbmContext().isGeneratedByEMF() &amp;&amp; =
eclassifier.getInstanceClass()=20
!=3D null) {<BR>&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp;propElement.addElement("type").addAttribute( "name",=20
getEnumUserType(enumerated))<BR>&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp;&nbsp;.addElement("param").addAttribute( "name",=20
HbMapperConstants.ENUM_CLASS_PARAM)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;.addText(eclassifier.getInstanceClass().getName( )); <BR>&nbsp;&nbs=
p;}=20
<BR>&nbsp;&nbsp;//--- JJH<BR>&nbsp;&nbsp;else if (true) { //&nbsp;would =
be a=20
property<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;// brute force this =
to=20
behave by letting the user specify what package should be=20
used.<BR>&nbsp;&nbsp;&nbsp;// If this is not enabled, enumerations are =
treated=20
as the wrong type.<BR>&nbsp;&nbsp;&nbsp;// This is ONLY needed if you =
are=20
generating .hbm directly from .ecore without using annotated class=20
files.&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;String packageName =3D=20
eclassifier.getEPackage().getNsPrefix();<BR>&nbsp;&nbsp;&nbsp;propElement=
..addElement("type").addAttribute("name",=20
getEnumUserType(enumerated))<BR>&nbsp;&nbsp;&nbsp;&nbsp;.addElement( "para=
m").addAttribute("name",=20
HbMapperConstants.ENUM_CLASS_PARAM)<BR>&nbsp;&nbsp;&nbsp;&nbsp;.addText(p=
ackageName+"."+eclassifier.getName());<BR>&nbsp;&nbsp;} <BR>&nbsp;&nbsp;//=
---=20
JJH<BR>&nbsp;&nbsp;else { // must be emf =
dynamic<BR>&nbsp;&nbsp;&nbsp;final=20
Element typeElement=20
=3D<BR> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;propElemen t.addElement( "type").addAt=
tribute("name",<BR> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hbDynamicEnumType(=
enumerated));<BR>&nbsp;&nbsp;&nbsp;typeElement.addElement( "param").addAtt=
ribute("name",<BR> &nbsp;&nbsp;&nbsp;&nbsp;HbMapperConstants.EC LASSIFIER_P=
ARAM).addText(eclassifier.getName());<BR>&nbsp;&nbsp;&nbsp;typeElement.ad=
dElement("param").addAttribute("name",=20
HbMapperConstants.EPACKAGE_PARAM)<BR>&nbsp;&nbsp;&nbsp;&nbsp;.addText(ecl=
assifier.getEPackage().getNsURI());<BR>&nbsp;&nbsp;} </FONT></FONT></DIV>
<DIV><FONT face=3DCourier size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2><FONT =
face=3DCourier>&nbsp;}<BR></FONT><BR>=3D=3D PROBLEM=20
2:<BR>So if I fix the CCE above with that bit of hardcoding and =
still&nbsp;let=20
the output hbm look like this:<BR>&nbsp;&nbsp;&nbsp;&nbsp; &lt;class=20
entity-name=3D"Address" abstract=3D"false" lazy=3D"false"=20
discriminator-value=3D"Address" table=3D"`cmr3605t`"&gt;<BR>instead of =
how it should=20
look as in this example:<BR>&nbsp;&nbsp;&nbsp;&nbsp; &lt;class=20
name=3D"com.vsp.consumer.impl.AddressImpl" entity-name=3D"Address" =
abstract=3D"false"=20
lazy=3D"false" discriminator-value=3D"Address" =
table=3D"`cmr3605t`"&gt;<BR><BR>I end=20
up with this mess when I relate the objects&nbsp; (-530 means invalid =
foreign=20
key value.&nbsp; Basically, it doesn't know how to map the relationships =
and=20
puts a bad value into the jdbc=20
statement):<BR>------------------------<BR>2007/07/12 15:38:32:551 PDT =
[DEBUG]=20
SQL - /* insert RelatedConsumer */ insert into "cmr3602t" (e_id, =
"isd_lock_ct",=20
"consumer_sk", "related_cmr_sk",=20
"cmr_relate_cd" ,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp ;&nbsp;&nbsp;=20
"relate_start_dt", "relate_end_dt", "isd_lupd_id", econtainer_class,=20
e_container, e_container_featureid, "dtype") values (default, ?, ?, ?, =
?, ?, ?,=20
?, ?, ?, ?, 'RelatedConsumer')<BR>2007/07/12 15:38:32:566 PDT [DEBUG]=20
AbstractBatcher - about to close PreparedStatement (open =
PreparedStatements: 1,=20
globally: 1)<BR>2007/07/12 15:38:32:582 PDT [DEBUG] =
JDBCExceptionReporter -=20
could not insert: [RelatedConsumer] [/* insert RelatedConsumer */ insert =
into=20
"cmr3602t" (e_id, "isd_lock_ct", "consumer_sk", "related_cmr_sk",=20
"cmr_relate_cd", "relate_start_dt", "relate_end_dt", "isd_lupd_id",=20
econtainer_class, e_container, e_container_featureid, "dtype") values =
(default,=20
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'RelatedConsumer')]=20
&lt;com.ibm.db2.jcc.b.SqlException: DB2 SQL error: SQLCODE: -530, =
SQLSTATE:=20
23503, SQLERRMC:=20
DB2ADMIN.cmr3602t.FK778C01274EE35F59&gt;com.ibm.db2.jcc. b.SqlException: =
DB2 SQL=20
error: SQLCODE: -530, SQLSTATE: 23503, SQLERRMC:=20
DB2ADMIN.cmr3602t.FK778C01274EE35F59<BR>2007/07/12 15:38:32:582 PDT =
[WARN]=20
JDBCExceptionReporter - SQL Error: -530, SQLState: 23503<BR>2007/07/12=20
15:38:32:582 PDT [ERROR] JDBCExceptionReporter - DB2 SQL error: SQLCODE: =
-530,=20
SQLSTATE: 23503, SQLERRMC:=20
DB2ADMIN.cmr3602t.FK778C01274EE35F59<BR>org.hibernate.exception.Constrain=
tViolationException:=20
could not insert: [RelatedConsumer]<BR>at=20
org.hibernate.exception.SQLStateConverter.convert(SQLStateCo nverter.java:=
71)<BR>at=20
org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExce ptionHelper.j=
ava:43)<BR>at=20
org.hibernate.id.insert.AbstractReturningDelegate.performIns ert(AbstractR=
eturningDelegate.java:40)<BR>at=20
org.hibernate.persister.entity.AbstractEntityPersister.inser t(AbstractEnt=
ityPersister.java:2158)<BR>at=20
org.hibernate.persister.entity.AbstractEntityPersister.inser t(AbstractEnt=
ityPersister.java:2638)<BR>at=20
org.hibernate.action.EntityIdentityInsertAction.execute(Enti tyIdentityIns=
ertAction.java:48)<BR>-----------------------<BR><BR>I=20
solve this with this bit of code in EntityMapper.java:<BR><BR>private =
Element=20
createEntity(PAnnotatedEClass entity,<BR>&nbsp;&nbsp;&nbsp; =
&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; =
&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; =
&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp;InheritanceType inhStrategy, PAnnotatedEClass=20
superEntity,<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; =

&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; =
&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp;DiscriminatorValue dValue, Table table) {</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>&nbsp;&nbsp;...<BR></FONT><FONT =
face=3DArial=20
size=3D2>&nbsp;&nbsp;final Element target;</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>&nbsp;&nbsp;final String entityName =3D =

getHbmContext().getEntityName(eclass);<BR>&nbsp;&nbsp;final String =
isAbstractStr=20
=3D eclass.isAbstract() ? "true" : "false";<BR>&nbsp;&nbsp;if=20
(entity.isOnlyMapAsEntity()) {<BR> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
target =3D=20
getHbmContext().getCurrent().addElement(hbClassName);<BR>&nbsp;&nbsp;&nbs=
p;<BR>&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp;if (hasCompositeID(entity)) { // only for this =
specific=20
case<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; =
&nbsp;&nbsp;&nbsp;&nbsp;String foo=20
=3D=20
hbmContext.getInstanceClassName(entity.getAnnotatedEClass()) ; <BR>&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp; target.addAttribute("name", =
foo);<BR>&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;//--- hard =
code fix=20
for missing class files.<BR>&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp;else{&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp; =
&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp;&nbsp;//--- JJH<BR>&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; target.addAttribute("name",=20
entity.getAnnotatedEClass().getEPackage().getNsPrefix()+".impl. "+entity.g=
etEntity().getName()+"Impl");<BR>&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;//--- =
JJH<BR>&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;... <BR></FONT></DIV>
<DIV><FONT face=3DArial size=3D2>I probably need to fix the name =
attribute in more=20
places than this, but doing it here makes all my code work.</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>=3D=3D OTHER POSSIBLE =
SOLUTIONS:<BR></FONT></DIV>
<DIV><FONT face=3DArial size=3D2>I thought about putting the package =
prefix that I=20
need into a property, but that's no fun because I'd have to change it =
every time=20
I ran another ecore file through.&nbsp; Ideally there should be =
something in the=20
ecore that would hold the package name, but it's not there.&nbsp; And =
since I=20
can specify any random value for ecore:package in the xsd I really need =
to have=20
the right string in order for things to match up at runtime.&nbsp; =
</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>I considered adding annotation to the =
basic schema=20
level, but the annotations only come through on the actual entity =
objects.&nbsp;=20
I didn't want to re-specify the package on every entity because that =
seems even=20
more redundant than using nsPrefix.</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>I also found nsPrefix being used in a =
somewhat=20
similar way in the existing teneo code here:</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>HibernateFeatureMapEntry:</FONT></DIV>
<DIV><FONT size=3D2><FONT face=3DCourier>&nbsp;/** Code copied from=20
FeatureMapUtil.EntryImpl */<BR>&nbsp;public String toString()=20
{<BR>&nbsp;&nbsp;&nbsp;String prefix =3D=20
eStructuralFeature.getEContainingClass().getEPackage().getNs Prefix(); <BR>=
&nbsp;=20
&nbsp;eStructuralFeature.getName();<BR>&nbsp;&nbsp; return (prefix !=3D =
null=20
&amp;&amp; prefix.length() !=3D 0 ? prefix + ":" +=20
eStructuralFeature.getName()<BR>&nbsp;&nbsp;&nbsp; &nbsp; :=20
eStructuralFeature.getName())<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + "=3D" =
+=20
getValue();<BR>&nbsp;}<BR></FONT></FONT></DIV>
<DIV><FONT size=3D2><FONT face=3DCourier>and in=20
QualifyingEClassNameStrategy</FONT></FONT></DIV>
<DIV><FONT size=3D2><FONT face=3DCourier></FONT></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2><FONT face=3DCourier>&nbsp;public String =
toUniqueName(EClass=20
eClass) {<BR>&nbsp;&nbsp;&nbsp;if (eClass =3D=3D null) {<BR>&nbsp;&nbsp; =

&nbsp;&nbsp;throw new IllegalArgumentException("EClass cannot be=20
null.");<BR>&nbsp;&nbsp;&nbsp;}<BR>&nbsp; &nbsp;if (eClass =3D=3D =
EOBJECT_ECLASS)=20
{<BR>&nbsp;&nbsp;&nbsp; &nbsp;return=20
EOBJECT_ECLASS_NAME;<BR>&nbsp;&nbsp;&nbsp;}<BR >&nbsp; &nbsp;String =
nsPrefix =3D=20
eClass.getEPackage().getNsPrefix();<BR>&nbsp;&nbsp; if (nsPrefix =3D=3D =
null)=20
{<BR>&nbsp;&nbsp;&nbsp;&nbsp; nsPrefix =3D=20
eClass.getEPackage().getName();<BR>&nbsp;&nbsp;&nbsp;} <BR>&nbsp; =
&nbsp;return=20
nsPrefix + "." + =
eClass.getName();<BR>&nbsp;}<BR></FONT></DIV></FONT ><FONT=20
face=3DArial size=3D2>
<DIV>Not quite the same, but close enough that it seemed like a =
reasonable=20
fit.&nbsp; </DIV>
<DIV>I'm completely open to any other solution you might suggest.</DIV>
<DIV>&nbsp;</DIV>
<DIV>Remember that both of these problems do not exist if you're letting =
teneo=20
run when the classes are available.&nbsp; Its only when you run =
GenerateHBM=20
against an ecore with no other input and then force teneo to use that =
HBM that=20
you run into these troubles.</DIV>
<DIV>&nbsp;</DIV>
<DIV>Talk to you soon,</DIV>
<DIV>&nbsp;</DIV>
<DIV> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
Jason </DIV>
<DIV>&nbsp;</DIV>
<DIV>&nbsp;</DIV>
<DIV>&nbsp;</DIV>
<DIV></FONT>&nbsp;</DIV></BODY></HTML>

------=_NextPart_000_00E9_01C7C4A0.7B3D87F0--
Re: [ Teneo ] SDO class name problem [message #89690 is a reply to message #89649] Fri, 13 July 2007 07:07 Go to previous message
Martin Taal is currently offline Martin TaalFriend
Messages: 5468
Registered: July 2009
Senior Member
Hi Jason,
Does your enum value type implement EEnumLiteral?

How does the hbm look like for the second problem?

You can also send the ecore file to me so I can try this second issue.

The part of the code where you refer to where Teneo also uses the nsprefix is to create a unique
name for an EClass, this name is not a class name but just a unique string (which can be converted
back to the EClass).

gr. Martin

Jason Henriksen wrote:
>
> I agree that nsPrefix isn't the prettiest thing in the world, but
> without the java package I run into these two problems:
>
> == PROBLEM 1:
> When I first applied the fix in CVS I started seeing the enumerated
> types fail. I got this hbm
> <type
> name="org.eclipse.emf.teneo.hibernate.mapping.DynamicENumUserType ">
> <param name="eclassifier">RelationshipCodeType</param>
> <param name="epackage">http://vsp.com/</param>
> </type>
> Instead of the runtime generated hbm which looks like this:
> <type name="org.eclipse.emf.teneo.hibernate.mapping.ENumUserType" >
> <param
> name="enumClass">com.vsp.consumer.RelationshipCodeType</param >
> </type>
>
> The basic problem is that it tries cast DynamicENumUserType to the
> specific enumation type that I've defined, but that it doesn't know
> about from the ecore. Here's the exception:
>
> java.lang.ClassCastException: com.vsp.consumer.GenderCodeType
> Hibernate: /* insert Consumer */ insert into "cmr3601t" ("isd_lock_ct",
> "consumer_id", "name_prefix", "first_name", "middle_initial",
> "last_name", "name_suffix", "ssn", "date_of_birth", "gender_cd",
> "marital_status_cd", "citizenship_ind", "disability_ind",
> "ethnicity_cd", "other_id", "other_id_type_cd", "personal_info",
> "place_of_birth", "prefer_comm_method", "isd_lupd_id", econtainer_class,
> e_container, e_container_featureid, "dtype", "consumer_sk") values (?,
> ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
> 'Consumer', ?)
> at
> org.eclipse.emf.teneo.hibernate.mapping.DynamicENumUserType. nullSafeSet(DynamicENumUserType.java:137)
> at org.hibernate.type.CustomType.nullSafeSet(CustomType.java:14 6)
> at
> org.hibernate.persister.entity.AbstractEntityPersister.dehyd rate(AbstractEntityPersister.java:1997)
> at
> org.hibernate.persister.entity.AbstractEntityPersister.inser t(AbstractEntityPersister.java:2243)
> I solve this by altering AbstractMapper like this:
>
> private void handleEnumType(PAnnotatedEAttribute paAttribute, Element
> propElement) {
> final Enumerated enumerated = paAttribute.getEnumerated();
> assert (enumerated != null);
> final EAttribute eattr = paAttribute.getAnnotatedEAttribute();
> final EClassifier eclassifier = eattr.getEType();
> if (!getHbmContext().isGeneratedByEMF()
> && getHbmContext().getInstanceClass(eclassifier) != null) {
> final Class<?> instanceClass =
> getHbmContext().getInstanceClass(eclassifier);
> propElement.addElement("type").addAttribute("name",
> getEnumUserType(enumerated))
> .addElement("param").addAttribute("name",
> HbMapperConstants.ENUM_CLASS_PARAM)
> .addText(instanceClass.getName());
> } else if (getHbmContext().isGeneratedByEMF() &&
> eclassifier.getInstanceClass() != null) {
> propElement.addElement("type").addAttribute("name",
> getEnumUserType(enumerated))
> .addElement("param").addAttribute("name",
> HbMapperConstants.ENUM_CLASS_PARAM)
> .addText(eclassifier.getInstanceClass().getName());
> }
> //--- JJH
> else if (true) { // would be a property
>
> // brute force this to behave by letting the user specify what
> package should be used.
> // If this is not enabled, enumerations are treated as the wrong type.
> // This is ONLY needed if you are generating .hbm directly from
> .ecore without using annotated class files.
> String packageName = eclassifier.getEPackage().getNsPrefix();
> propElement..addElement("type").addAttribute("name",
> getEnumUserType(enumerated))
> .addElement("param").addAttribute("name",
> HbMapperConstants.ENUM_CLASS_PARAM)
> .addText(packageName+"."+eclassifier.getName());
> }
> //--- JJH
> else { // must be emf dynamic
> final Element typeElement =
> propElement.addElement("type").addAttribute("name",
> hbDynamicEnumType(enumerated));
> typeElement.addElement("param").addAttribute("name",
> HbMapperConstants.ECLASSIFIER_PARAM).addText(eclassifier.get Name());
> typeElement.addElement("param").addAttribute("name",
> HbMapperConstants.EPACKAGE_PARAM)
> .addText(eclassifier.getEPackage().getNsURI());
> }
>
> }
>
> == PROBLEM 2:
> So if I fix the CCE above with that bit of hardcoding and still let the
> output hbm look like this:
> <class entity-name="Address" abstract="false" lazy="false"
> discriminator-value="Address" table="`cmr3605t`">
> instead of how it should look as in this example:
> <class name="com.vsp.consumer.impl.AddressImpl"
> entity-name="Address" abstract="false" lazy="false"
> discriminator-value="Address" table="`cmr3605t`">
>
> I end up with this mess when I relate the objects (-530 means invalid
> foreign key value. Basically, it doesn't know how to map the
> relationships and puts a bad value into the jdbc statement):
> ------------------------
> 2007/07/12 15:38:32:551 PDT [DEBUG] SQL - /* insert RelatedConsumer */
> insert into "cmr3602t" (e_id, "isd_lock_ct", "consumer_sk",
> "related_cmr_sk", "cmr_relate_cd", "relate_start_dt",
> "relate_end_dt", "isd_lupd_id", econtainer_class, e_container,
> e_container_featureid, "dtype") values (default, ?, ?, ?, ?, ?, ?, ?, ?,
> ?, ?, 'RelatedConsumer')
> 2007/07/12 15:38:32:566 PDT [DEBUG] AbstractBatcher - about to close
> PreparedStatement (open PreparedStatements: 1, globally: 1)
> 2007/07/12 15:38:32:582 PDT [DEBUG] JDBCExceptionReporter - could not
> insert: [RelatedConsumer] [/* insert RelatedConsumer */ insert into
> "cmr3602t" (e_id, "isd_lock_ct", "consumer_sk", "related_cmr_sk",
> "cmr_relate_cd", "relate_start_dt", "relate_end_dt", "isd_lupd_id",
> econtainer_class, e_container, e_container_featureid, "dtype") values
> (default, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'RelatedConsumer')]
> <com.ibm.db2.jcc.b.SqlException: DB2 SQL error: SQLCODE: -530, SQLSTATE:
> 23503, SQLERRMC:
> DB2ADMIN.cmr3602t.FK778C01274EE35F59>com.ibm.db2.jcc.b.SqlException: DB2
> SQL error: SQLCODE: -530, SQLSTATE: 23503, SQLERRMC:
> DB2ADMIN.cmr3602t.FK778C01274EE35F59
> 2007/07/12 15:38:32:582 PDT [WARN] JDBCExceptionReporter - SQL Error:
> -530, SQLState: 23503
> 2007/07/12 15:38:32:582 PDT [ERROR] JDBCExceptionReporter - DB2 SQL
> error: SQLCODE: -530, SQLSTATE: 23503, SQLERRMC:
> DB2ADMIN.cmr3602t.FK778C01274EE35F59
> org.hibernate.exception.ConstraintViolationException: could not insert:
> [RelatedConsumer]
> at
> org.hibernate.exception.SQLStateConverter.convert(SQLStateCo nverter.java:71)
> at
> org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExce ptionHelper.java:43)
> at
> org.hibernate.id.insert.AbstractReturningDelegate.performIns ert(AbstractReturningDelegate.java:40)
> at
> org.hibernate.persister.entity.AbstractEntityPersister.inser t(AbstractEntityPersister.java:2158)
> at
> org.hibernate.persister.entity.AbstractEntityPersister.inser t(AbstractEntityPersister.java:2638)
> at
> org.hibernate.action.EntityIdentityInsertAction.execute(Enti tyIdentityInsertAction.java:48)
> -----------------------
>
> I solve this with this bit of code in EntityMapper.java:
>
> private Element createEntity(PAnnotatedEClass entity,
> InheritanceType inhStrategy,
> PAnnotatedEClass superEntity,
> DiscriminatorValue dValue,
> Table table) {
>
> ...
> final Element target;
>
> final String entityName = getHbmContext().getEntityName(eclass);
> final String isAbstractStr = eclass.isAbstract() ? "true" : "false";
> if (entity.isOnlyMapAsEntity()) {
> target = getHbmContext().getCurrent().addElement(hbClassName);
>
> if (hasCompositeID(entity)) { // only for this specific case
> String foo =
> hbmContext.getInstanceClassName(entity.getAnnotatedEClass()) ;
> target.addAttribute("name", foo);
> }
> //--- hard code fix for missing class files.
> else{
> //--- JJH
> target.addAttribute("name",
> entity.getAnnotatedEClass().getEPackage().getNsPrefix()+".impl. "+entity.getEntity().getName()+"Impl");
> //--- JJH
> }
> ...
> I probably need to fix the name attribute in more places than this, but
> doing it here makes all my code work.
>
> == OTHER POSSIBLE SOLUTIONS:
> I thought about putting the package prefix that I need into a property,
> but that's no fun because I'd have to change it every time I ran another
> ecore file through. Ideally there should be something in the ecore that
> would hold the package name, but it's not there. And since I can
> specify any random value for ecore:package in the xsd I really need to
> have the right string in order for things to match up at runtime.
>
> I considered adding annotation to the basic schema level, but the
> annotations only come through on the actual entity objects. I didn't
> want to re-specify the package on every entity because that seems even
> more redundant than using nsPrefix.
>
> I also found nsPrefix being used in a somewhat similar way in the
> existing teneo code here:
>
> HibernateFeatureMapEntry:
> /** Code copied from FeatureMapUtil.EntryImpl */
> public String toString() {
> String prefix =
> eStructuralFeature.getEContainingClass().getEPackage().getNs Prefix();
> eStructuralFeature.getName();
> return (prefix != null && prefix.length() != 0 ? prefix + ":" +
> eStructuralFeature.getName()
> : eStructuralFeature.getName())
> + "=" + getValue();
> }
> and in QualifyingEClassNameStrategy
>
> public String toUniqueName(EClass eClass) {
> if (eClass == null) {
> throw new IllegalArgumentException("EClass cannot be null.");
> }
> if (eClass == EOBJECT_ECLASS) {
> return EOBJECT_ECLASS_NAME;
> }
> String nsPrefix = eClass.getEPackage().getNsPrefix();
> if (nsPrefix == null) {
> nsPrefix = eClass.getEPackage().getName();
> }
> return nsPrefix + "." + eClass.getName();
> }
> Not quite the same, but close enough that it seemed like a reasonable fit.
> I'm completely open to any other solution you might suggest.
>
> Remember that both of these problems do not exist if you're letting
> teneo run when the classes are available. Its only when you run
> GenerateHBM against an ecore with no other input and then force teneo to
> use that HBM that you run into these troubles.
>
> Talk to you soon,
>
> Jason
>
>
>
>


--

With Regards, Martin Taal

Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
Re: [ Teneo ] SDO class name problem [message #608703 is a reply to message #89071] Wed, 11 July 2007 19:28 Go to previous message
Martin Taal is currently offline Martin TaalFriend
Messages: 5468
Registered: July 2009
Senior Member
Hi Jason,
I am not sure how you got the DynamicEObjectImpl in the hbm file.
This happens in case of a dynamic emf model (without generated java code). This is a current bug:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=193052
I have solved this in cvs. If it is this bug then to work around this for now you can remove this
from the hbm:
name="org.eclipse.emf.ecore.impl.DynamicEObjectImpl"
(a global search and replace will work)

Still, I don't really understand why it does not pick up the CustomerImpl class.
You can also programmatically create the hbm file (see the HbHelper class) this is safer from a
classloading point of view and allows you to pass options when generating the hbm.

gr. Martin

Jason Henriksen wrote:
> Hi Again,
>
> So having sorted out how to make a Teno generated HBM get used, I found my
> next difficulty. I'm using the genmodel to create SDO objects and when Teno
> reads the sdo objects to build the mapping everything works great and I get
> hbm that looks like this:
>
> <class name="com.vsp.consumer.impl.ConsumerImpl"
> entity-name="Consumer"
> abstract="false" lazy="false" discriminator-value="Consumer"
> table="`cmr3601t`">
> <meta attribute="eclassName">Consumer</meta>
>
> The key thing here is taht the name="com.vsp.consumer.impl.ConsumerImpl"
>
> <class name="org.eclipse.emf.ecore.impl.DynamicEObjectImpl"
> entity-name="Consumer"
> abstract="false" lazy="false" discriminator-value="Consumer"
> table="`cmr3601t`">
> <meta attribute="eclassName">Consumer</meta>
>
> This blows up when I try to use this hbm because the data store
> initialization expects DynamicEObjectImpl to have getters and setters for
> all my fields in the same way that ConsumerImpl does.
>
> I use the "Set SDO defaults" on the gen model before I generate the model
> code since I have to have pojos for my clients to interact with. Is there
> some similar configuration that I need to set for Teneo to put the correct
> names in place?
>
> If there's a feature enhancement to be done here, let me know. I'm looking
> at the code as well, but I thought I'd ask since the solution isn't jumping
> out at me.
>
> I've gotten my local teneo version to put <comment> tags into the hbm from
> the ecore. Once I can fix this and prove that that my objects will work,
> I'll be about ready to submit that to you as well.
>
> Jason Henriksen
>
>


--

With Regards, Martin Taal

Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
Re: [ Teneo ] SDO class name problem [message #608733 is a reply to message #89086] Thu, 12 July 2007 20:20 Go to previous message
Jason Henriksen is currently offline Jason HenriksenFriend
Messages: 231
Registered: July 2009
Senior Member
Hi Martin,

> I am not sure how you got the DynamicEObjectImpl in the hbm file.
> This happens in case of a dynamic emf model (without generated java code).
This is a current bug:
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=193052

For me, the class name information is not present because I run teneo with
only the ecore available by invoding the main in GenerateHBM. I tried
putting the SDO classes into the class path but it wasn't enough and no good
naming was found.

> I have solved this in cvs. If it is this bug then to work around this for
now you can remove this
> from the hbm:
> name="org.eclipse.emf.ecore.impl.DynamicEObjectImpl"

Applying the fix from CVS also didn't work out completely. It helped in
that the name attribute was not present until runtime and so the mappings
would generate but two other problems came up:
- Enumeration types still failed because the name wasn't present and so it
couldn't find the correct values
- Relationships didn't work because the keys information couldn't be found.

So I used teneo at run time, captured the output HBM and kept hacking at the
ecore-only generation method until I could get the same result. The main
problem was that there was no way to get the java package because that
information doesn't get put in the .ecore file.

I control the output package for the java files by using ecore:package like
this:

<xsd:schema targetNamespace="http://vsp.com/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:vsp="http://vsp.com/"
xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
ecore:package="com.vsp.consumer">

But ecore:package only goes to the genmodel, not to the ecore file. Luckily
I discovered nsPrefix:

<xsd:schema targetNamespace="http://vsp.com/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:vsp="http://vsp.com/"
xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
ecore:package="com.vsp.consumer"
ecore:nsPrefix="com.vsp.consumer">

By putting this into the XSD, I can get a hold of it in the ecore. From
there I generate all the names in the same way that the SDO code generator
will and everything comes out perfectly. The names are specified correctly,
the keys and the enums all work great.

Basically, I keep the current fix, but when I'm generating the xml for the
entity I add

target.addAttribute("name",
entity.getAnnotatedEClass().getEPackage().getNsPrefix()+".impl. "+
entity.getEntity().getName()+"Impl");

I'd like to make another property that will control wether or not to use the
nsPrefix like that. It seems like this is what the nsPrefix attribute was
put in there for and as fas as I can tell teneo isn't really using it any
differently in the few places that it uses it at all. I was thinking about
a property like USE_NS_PREFIX_FOR_JAVA_NAME_GENERATION to control wether
this gets used or not, but whatever you like is good for me.

Let me know what you think, and I'll make another submission for this. I'll
keep three submissions seperate so you can review them individually. I've
got Comments, UseSpecificHBMFile and now nsPrefixForPackage as the three
things I'm about ready to send your way.

Talk to you soon,

Jason Henriksen
Re: [ Teneo ] SDO class name problem [message #608734 is a reply to message #89544] Thu, 12 July 2007 20:32 Go to previous message
Martin Taal is currently offline Martin TaalFriend
Messages: 5468
Registered: July 2009
Senior Member
Hi Jason,
I am not sure about using the nsprefix. Teneo/Hibernate should also work with dynamic emf (so no
generated java code). What goes exactly wrong in these two cases?
> - Enumeration types still failed because the name wasn't present and so it
> couldn't find the correct values
> - Relationships didn't work because the keys information couldn't be found.

How does the hbm look like in this case?

gr. Martin

Jason Henriksen wrote:
> Hi Martin,
>
>> I am not sure how you got the DynamicEObjectImpl in the hbm file.
>> This happens in case of a dynamic emf model (without generated java code).
> This is a current bug:
>> https://bugs.eclipse.org/bugs/show_bug.cgi?id=193052
>
> For me, the class name information is not present because I run teneo with
> only the ecore available by invoding the main in GenerateHBM. I tried
> putting the SDO classes into the class path but it wasn't enough and no good
> naming was found.
>
>> I have solved this in cvs. If it is this bug then to work around this for
> now you can remove this
>> from the hbm:
>> name="org.eclipse.emf.ecore.impl.DynamicEObjectImpl"
>
> Applying the fix from CVS also didn't work out completely. It helped in
> that the name attribute was not present until runtime and so the mappings
> would generate but two other problems came up:
> - Enumeration types still failed because the name wasn't present and so it
> couldn't find the correct values
> - Relationships didn't work because the keys information couldn't be found.
>
> So I used teneo at run time, captured the output HBM and kept hacking at the
> ecore-only generation method until I could get the same result. The main
> problem was that there was no way to get the java package because that
> information doesn't get put in the .ecore file.
>
> I control the output package for the java files by using ecore:package like
> this:
>
> <xsd:schema targetNamespace="http://vsp.com/"
> xmlns:xsd="http://www.w3.org/2001/XMLSchema"
> xmlns:vsp="http://vsp.com/"
> xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
> ecore:package="com.vsp.consumer">
>
> But ecore:package only goes to the genmodel, not to the ecore file. Luckily
> I discovered nsPrefix:
>
> <xsd:schema targetNamespace="http://vsp.com/"
> xmlns:xsd="http://www.w3.org/2001/XMLSchema"
> xmlns:vsp="http://vsp.com/"
> xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
> ecore:package="com.vsp.consumer"
> ecore:nsPrefix="com.vsp.consumer">
>
> By putting this into the XSD, I can get a hold of it in the ecore. From
> there I generate all the names in the same way that the SDO code generator
> will and everything comes out perfectly. The names are specified correctly,
> the keys and the enums all work great.
>
> Basically, I keep the current fix, but when I'm generating the xml for the
> entity I add
>
> target.addAttribute("name",
> entity.getAnnotatedEClass().getEPackage().getNsPrefix()+".impl. "+
> entity.getEntity().getName()+"Impl");
>
> I'd like to make another property that will control wether or not to use the
> nsPrefix like that. It seems like this is what the nsPrefix attribute was
> put in there for and as fas as I can tell teneo isn't really using it any
> differently in the few places that it uses it at all. I was thinking about
> a property like USE_NS_PREFIX_FOR_JAVA_NAME_GENERATION to control wether
> this gets used or not, but whatever you like is good for me.
>
> Let me know what you think, and I'll make another submission for this. I'll
> keep three submissions seperate so you can review them individually. I've
> got Comments, UseSpecificHBMFile and now nsPrefixForPackage as the three
> things I'm about ready to send your way.
>
> Talk to you soon,
>
> Jason Henriksen
>
>
>
>


--

With Regards, Martin Taal

Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
Re: [ Teneo ] SDO class name problem [message #608739 is a reply to message #89559] Thu, 12 July 2007 23:19 Go to previous message
Jason Henriksen is currently offline Jason HenriksenFriend
Messages: 231
Registered: July 2009
Senior Member
This is a multi-part message in MIME format.

------=_NextPart_000_00E9_01C7C4A0.7B3D87F0
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable


I agree that nsPrefix isn't the prettiest thing in the world, but =
without the java package I run into these two problems:

=3D=3D PROBLEM 1:
When I first applied the fix in CVS I started seeing the enumerated =
types fail. I got this hbm
<type =
name=3D"org.eclipse.emf.teneo.hibernate.mapping.DynamicENumUserType ">
<param name=3D"eclassifier">RelationshipCodeType</param>
<param name=3D"epackage">http://vsp.com/</param>
</type>
Instead of the runtime generated hbm which looks like this:
<type =
name=3D"org.eclipse.emf.teneo.hibernate.mapping.ENumUserType ">
<param =
name=3D"enumClass">com.vsp.consumer.RelationshipCodeType</param >
</type>

The basic problem is that it tries cast DynamicENumUserType to the =
specific enumation type that I've defined, but that it doesn't know =
about from the ecore. Here's the exception:

java.lang.ClassCastException: com.vsp.consumer.GenderCodeType
Hibernate: /* insert Consumer */ insert into "cmr3601t" ("isd_lock_ct", =
"consumer_id", "name_prefix", "first_name", "middle_initial", =
"last_name", "name_suffix", "ssn", "date_of_birth", "gender_cd", =
"marital_status_cd", "citizenship_ind", "disability_ind", =
"ethnicity_cd", "other_id", "other_id_type_cd", "personal_info", =
"place_of_birth", "prefer_comm_method", "isd_lupd_id", econtainer_class, =
e_container, e_container_featureid, "dtype", "consumer_sk") values (?, =
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, =
'Consumer', ?)
at =
org.eclipse.emf.teneo.hibernate.mapping.DynamicENumUserType. nullSafeSet(D=
ynamicENumUserType.java:137)
at org.hibernate.type.CustomType.nullSafeSet(CustomType.java:14 6)
at =
org.hibernate.persister.entity.AbstractEntityPersister.dehyd rate(Abstract=
EntityPersister.java:1997)
at =
org.hibernate.persister.entity.AbstractEntityPersister.inser t(AbstractEnt=
ityPersister.java:2243)

I solve this by altering AbstractMapper like this:

private void handleEnumType(PAnnotatedEAttribute paAttribute, Element =
propElement) {
final Enumerated enumerated =3D paAttribute.getEnumerated();
assert (enumerated !=3D null);
final EAttribute eattr =3D paAttribute.getAnnotatedEAttribute();
final EClassifier eclassifier =3D eattr.getEType();
if (!getHbmContext().isGeneratedByEMF()
&& getHbmContext().getInstanceClass(eclassifier) !=3D null) {
final Class<?> instanceClass =3D =
getHbmContext().getInstanceClass(eclassifier);
propElement.addElement("type").addAttribute("name", =
getEnumUserType(enumerated))
.addElement("param").addAttribute("name", =
HbMapperConstants.ENUM_CLASS_PARAM)
.addText(instanceClass.getName());
} else if (getHbmContext().isGeneratedByEMF() && =
eclassifier.getInstanceClass() !=3D null) {
propElement.addElement("type").addAttribute("name", =
getEnumUserType(enumerated))
.addElement("param").addAttribute("name", =
HbMapperConstants.ENUM_CLASS_PARAM)
.addText(eclassifier.getInstanceClass().getName());
}=20
//--- JJH
else if (true) { // would be a property
=20
// brute force this to behave by letting the user specify what =
package should be used.
// If this is not enabled, enumerations are treated as the wrong =
type.
// This is ONLY needed if you are generating .hbm directly from =
..ecore without using annotated class files. =20
String packageName =3D eclassifier.getEPackage().getNsPrefix();
propElement.addElement("type").addAttribute("name", =
getEnumUserType(enumerated))
.addElement("param").addAttribute("name", =
HbMapperConstants.ENUM_CLASS_PARAM)
.addText(packageName+"."+eclassifier.getName());
}
//--- JJH
else { // must be emf dynamic
final Element typeElement =3D
propElement.addElement("type").addAttribute("name",
hbDynamicEnumType(enumerated));
typeElement.addElement("param").addAttribute("name",
HbMapperConstants.ECLASSIFIER_PARAM).addText(eclassifier.get Name());
typeElement.addElement("param").addAttribute("name", =
HbMapperConstants.EPACKAGE_PARAM)
.addText(eclassifier.getEPackage().getNsURI());
}

}

=3D=3D PROBLEM 2:
So if I fix the CCE above with that bit of hardcoding and still let the =
output hbm look like this:
<class entity-name=3D"Address" abstract=3D"false" lazy=3D"false" =
discriminator-value=3D"Address" table=3D"`cmr3605t`">
instead of how it should look as in this example:
<class name=3D"com.vsp.consumer.impl.AddressImpl" =
entity-name=3D"Address" abstract=3D"false" lazy=3D"false" =
discriminator-value=3D"Address" table=3D"`cmr3605t`">

I end up with this mess when I relate the objects (-530 means invalid =
foreign key value. Basically, it doesn't know how to map the =
relationships and puts a bad value into the jdbc statement):
------------------------
2007/07/12 15:38:32:551 PDT [DEBUG] SQL - /* insert RelatedConsumer */ =
insert into "cmr3602t" (e_id, "isd_lock_ct", "consumer_sk", =
"related_cmr_sk", "cmr_relate_cd", "relate_start_dt", =
"relate_end_dt", "isd_lupd_id", econtainer_class, e_container, =
e_container_featureid, "dtype") values (default, ?, ?, ?, ?, ?, ?, ?, ?, =
?, ?, 'RelatedConsumer')
2007/07/12 15:38:32:566 PDT [DEBUG] AbstractBatcher - about to close =
PreparedStatement (open PreparedStatements: 1, globally: 1)
2007/07/12 15:38:32:582 PDT [DEBUG] JDBCExceptionReporter - could not =
insert: [RelatedConsumer] [/* insert RelatedConsumer */ insert into =
"cmr3602t" (e_id, "isd_lock_ct", "consumer_sk", "related_cmr_sk", =
"cmr_relate_cd", "relate_start_dt", "relate_end_dt", "isd_lupd_id", =
econtainer_class, e_container, e_container_featureid, "dtype") values =
(default, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'RelatedConsumer')] =
<com.ibm.db2.jcc.b.SqlException: DB2 SQL error: SQLCODE: -530, SQLSTATE: =
23503, SQLERRMC: =
DB2ADMIN.cmr3602t.FK778C01274EE35F59>com.ibm.db2.jcc.b.SqlException: DB2 =
SQL error: SQLCODE: -530, SQLSTATE: 23503, SQLERRMC: =
DB2ADMIN.cmr3602t.FK778C01274EE35F59
2007/07/12 15:38:32:582 PDT [WARN] JDBCExceptionReporter - SQL Error: =
-530, SQLState: 23503
2007/07/12 15:38:32:582 PDT [ERROR] JDBCExceptionReporter - DB2 SQL =
error: SQLCODE: -530, SQLSTATE: 23503, SQLERRMC: =
DB2ADMIN.cmr3602t.FK778C01274EE35F59
org.hibernate.exception.ConstraintViolationException: could not insert: =
[RelatedConsumer]
at =
org.hibernate.exception.SQLStateConverter.convert(SQLStateCo nverter.java:=
71)
at =
org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExce ptionHelper.j=
ava:43)
at =
org.hibernate.id.insert.AbstractReturningDelegate.performIns ert(AbstractR=
eturningDelegate.java:40)
at =
org.hibernate.persister.entity.AbstractEntityPersister.inser t(AbstractEnt=
ityPersister.java:2158)
at =
org.hibernate.persister.entity.AbstractEntityPersister.inser t(AbstractEnt=
ityPersister.java:2638)
at =
org.hibernate.action.EntityIdentityInsertAction.execute(Enti tyIdentityIns=
ertAction.java:48)
-----------------------

I solve this with this bit of code in EntityMapper.java:

private Element createEntity(PAnnotatedEClass entity,
InheritanceType inhStrategy, =
PAnnotatedEClass superEntity,
DiscriminatorValue dValue, =
Table table) {

...
final Element target;

final String entityName =3D getHbmContext().getEntityName(eclass);
final String isAbstractStr =3D eclass.isAbstract() ? "true" : "false";
if (entity.isOnlyMapAsEntity()) {
target =3D getHbmContext().getCurrent().addElement(hbClassName);
=20
if (hasCompositeID(entity)) { // only for this specific case
String foo =3D =
hbmContext.getInstanceClassName(entity.getAnnotatedEClass()) ;
target.addAttribute("name", foo);
}
//--- hard code fix for missing class files.
else{ =20
//--- JJH
target.addAttribute("name", =
entity.getAnnotatedEClass().getEPackage().getNsPrefix()+".impl. "+entity.g=
etEntity().getName()+"Impl");
//--- JJH
}
...

I probably need to fix the name attribute in more places than this, but =
doing it here makes all my code work.

=3D=3D OTHER POSSIBLE SOLUTIONS:

I thought about putting the package prefix that I need into a property, =
but that's no fun because I'd have to change it every time I ran another =
ecore file through. Ideally there should be something in the ecore that =
would hold the package name, but it's not there. And since I can =
specify any random value for ecore:package in the xsd I really need to =
have the right string in order for things to match up at runtime. =20

I considered adding annotation to the basic schema level, but the =
annotations only come through on the actual entity objects. I didn't =
want to re-specify the package on every entity because that seems even =
more redundant than using nsPrefix.

I also found nsPrefix being used in a somewhat similar way in the =
existing teneo code here:

HibernateFeatureMapEntry:
/** Code copied from FeatureMapUtil.EntryImpl */
public String toString() {
String prefix =3D =
eStructuralFeature.getEContainingClass().getEPackage().getNs Prefix();
eStructuralFeature.getName();
return (prefix !=3D null && prefix.length() !=3D 0 ? prefix + ":" + =
eStructuralFeature.getName()
: eStructuralFeature.getName())
+ "=3D" + getValue();
}

and in QualifyingEClassNameStrategy

public String toUniqueName(EClass eClass) {
if (eClass =3D=3D null) {
throw new IllegalArgumentException("EClass cannot be null.");
}
if (eClass =3D=3D EOBJECT_ECLASS) {
return EOBJECT_ECLASS_NAME;
}
String nsPrefix =3D eClass.getEPackage().getNsPrefix();
if (nsPrefix =3D=3D null) {
nsPrefix =3D eClass.getEPackage().getName();
}
return nsPrefix + "." + eClass.getName();
}

Not quite the same, but close enough that it seemed like a reasonable =
fit. =20
I'm completely open to any other solution you might suggest.

Remember that both of these problems do not exist if you're letting =
teneo run when the classes are available. Its only when you run =
GenerateHBM against an ecore with no other input and then force teneo to =
use that HBM that you run into these troubles.

Talk to you soon,

Jason=20




------=_NextPart_000_00E9_01C7C4A0.7B3D87F0
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=3DContent-Type content=3D"text/html; =
charset=3Diso-8859-1">
<META content=3D"MSHTML 6.00.2800.1561" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=3D#ffffff background=3D""><FONT face=3DArial =
size=3D2></FONT><FONT=20
face=3DArial size=3D2></FONT>
<DIV><FONT face=3DArial size=3D2></FONT><BR><FONT face=3DArial =
size=3D2>I agree that=20
nsPrefix isn't the prettiest thing in the world, but without the java =
package I=20
run into these two problems:<BR><BR>=3D=3D PROBLEM 1:<BR>When I first =
applied the=20
fix in CVS I started seeing the enumerated types fail.&nbsp; I got this=20
hbm</FONT></DIV>
<DIV><FONT face=3DArial =
size=3D2> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;=20
&lt;type=20
name=3D"org.eclipse.emf.teneo.hibernate.mapping.DynamicENumUserType "&gt;<=
BR>&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &lt;param=20
name=3D"eclassifier"&gt;RelationshipCodeType&lt;/param&gt; <BR>&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp ;&nbsp;&nbsp;&nbsp;=20
&lt;param =
name=3D"epackage"&gt;http://vsp.com/&lt;/param&gt;<BR>&nbsp;&nbsp;&nbsp; =

&nbsp;&nbsp;&nbsp;&nbsp; &lt;/type&gt;<BR></FONT><FONT face=3DArial =
size=3D2>Instead=20
of the runtime generated hbm which looks like this:</FONT></DIV>
<DIV><FONT face=3DArial =
size=3D2> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;=20
&lt;type=20
name=3D"org.eclipse.emf.teneo.hibernate.mapping.ENumUserType "&gt;<BR>&nbs=
p;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&lt;param=20
name=3D"enumClass" &gt;com.vsp.consumer.RelationshipCodeType&lt;/param& amp;gt;=
<BR>&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp;&nbsp; &lt;/type&gt;<BR></FONT><FONT face=3DArial =
size=3D2><BR>The=20
basic problem is that it tries cast DynamicENumUserType to the specific=20
enumation type that I've defined, but that it doesn't know about from =
the=20
ecore.&nbsp; Here's the exception:</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>java.lang.ClassCastException:=20
com.vsp.consumer.GenderCodeType<BR>Hibernate: /* insert Consumer */ =
insert into=20
"cmr3601t" ("isd_lock_ct", "consumer_id", "name_prefix", "first_name",=20
"middle_initial", "last_name", "name_suffix", "ssn", "date_of_birth",=20
"gender_cd", "marital_status_cd", "citizenship_ind", "disability_ind",=20
"ethnicity_cd", "other_id", "other_id_type_cd", "personal_info",=20
"place_of_birth", "prefer_comm_method", "isd_lupd_id", econtainer_class, =

e_container, e_container_featureid, "dtype", "consumer_sk") values (?, =
?, ?, ?,=20
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'Consumer',=20
?)<BR>&nbsp;&nbsp;&nbsp; &nbsp;at=20
org.eclipse.emf.teneo.hibernate.mapping.DynamicENumUserType. nullSafeSet(D=
ynamicENumUserType.java:137)<BR>&nbsp;&nbsp;&nbsp;=20
&nbsp;at=20
org.hibernate.type.CustomType.nullSafeSet(CustomType.java:14 6) <BR>&nbsp;&=
nbsp;&nbsp;=20
&nbsp;at=20
org.hibernate.persister.entity.AbstractEntityPersister.dehyd rate(Abstract=
EntityPersister.java:1997)<BR>&nbsp;&nbsp;&nbsp;=20
&nbsp;at=20
org.hibernate.persister.entity.AbstractEntityPersister.inser t(AbstractEnt=
ityPersister.java:2243)<BR></DIV></FONT>
<DIV><FONT face=3DArial size=3D2>I solve this by altering AbstractMapper =
like=20
this:</FONT></DIV>
<DIV><FONT face=3DArial size=3D2><BR><FONT face=3DCourier>&nbsp;private =
void=20
handleEnumType(PAnnotatedEAttribute paAttribute, Element propElement)=20
{<BR>&nbsp;&nbsp;final Enumerated enumerated =3D=20
paAttribute.getEnumerated();<BR>&nbsp;&nbsp;assert (enumerated !=3D=20
null);<BR>&nbsp;&nbsp;final EAttribute eattr =3D=20
paAttribute.getAnnotatedEAttribute();<BR>&nbsp;&nbsp;final EClassifier=20
eclassifier =3D eattr.getEType();<BR>&nbsp;&nbsp;if=20
(!getHbmContext().isGeneratedByEMF()<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&amp;&amp;=20
getHbmContext().getInstanceClass(eclassifier) !=3D null) =
{<BR>&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp;final Class&lt;?&gt; instanceClass =3D=20
getHbmContext().getInstanceClass(eclassifier);<BR>&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp;propElement.addElement("type").addAttribute( "name",=20
getEnumUserType(enumerated))<BR>&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp;&nbsp;.addElement("param").addAttribute( "name",=20
HbMapperConstants.ENUM_CLASS_PARAM)<BR>&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp;&nbsp;.addText(instanceCla ss.getName()); <BR>&nbsp;&nbsp=
;} else=20
if (getHbmContext().isGeneratedByEMF() &amp;&amp; =
eclassifier.getInstanceClass()=20
!=3D null) {<BR>&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp;propElement.addElement("type").addAttribute( "name",=20
getEnumUserType(enumerated))<BR>&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp;&nbsp;.addElement("param").addAttribute( "name",=20
HbMapperConstants.ENUM_CLASS_PARAM)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;.addText(eclassifier.getInstanceClass().getName( )); <BR>&nbsp;&nbs=
p;}=20
<BR>&nbsp;&nbsp;//--- JJH<BR>&nbsp;&nbsp;else if (true) { //&nbsp;would =
be a=20
property<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;// brute force this =
to=20
behave by letting the user specify what package should be=20
used.<BR>&nbsp;&nbsp;&nbsp;// If this is not enabled, enumerations are =
treated=20
as the wrong type.<BR>&nbsp;&nbsp;&nbsp;// This is ONLY needed if you =
are=20
generating .hbm directly from .ecore without using annotated class=20
files.&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;String packageName =3D=20
eclassifier.getEPackage().getNsPrefix();<BR>&nbsp;&nbsp;&nbsp;propElement=
..addElement("type").addAttribute("name",=20
getEnumUserType(enumerated))<BR>&nbsp;&nbsp;&nbsp;&nbsp;.addElement( "para=
m").addAttribute("name",=20
HbMapperConstants.ENUM_CLASS_PARAM)<BR>&nbsp;&nbsp;&nbsp;&nbsp;.addText(p=
ackageName+"."+eclassifier.getName());<BR>&nbsp;&nbsp;} <BR>&nbsp;&nbsp;//=
---=20
JJH<BR>&nbsp;&nbsp;else { // must be emf =
dynamic<BR>&nbsp;&nbsp;&nbsp;final=20
Element typeElement=20
=3D<BR> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;propElemen t.addElement( "type").addAt=
tribute("name",<BR> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hbDynamicEnumType(=
enumerated));<BR>&nbsp;&nbsp;&nbsp;typeElement.addElement( "param").addAtt=
ribute("name",<BR> &nbsp;&nbsp;&nbsp;&nbsp;HbMapperConstants.EC LASSIFIER_P=
ARAM).addText(eclassifier.getName());<BR>&nbsp;&nbsp;&nbsp;typeElement.ad=
dElement("param").addAttribute("name",=20
HbMapperConstants.EPACKAGE_PARAM)<BR>&nbsp;&nbsp;&nbsp;&nbsp;.addText(ecl=
assifier.getEPackage().getNsURI());<BR>&nbsp;&nbsp;} </FONT></FONT></DIV>
<DIV><FONT face=3DCourier size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2><FONT =
face=3DCourier>&nbsp;}<BR></FONT><BR>=3D=3D PROBLEM=20
2:<BR>So if I fix the CCE above with that bit of hardcoding and =
still&nbsp;let=20
the output hbm look like this:<BR>&nbsp;&nbsp;&nbsp;&nbsp; &lt;class=20
entity-name=3D"Address" abstract=3D"false" lazy=3D"false"=20
discriminator-value=3D"Address" table=3D"`cmr3605t`"&gt;<BR>instead of =
how it should=20
look as in this example:<BR>&nbsp;&nbsp;&nbsp;&nbsp; &lt;class=20
name=3D"com.vsp.consumer.impl.AddressImpl" entity-name=3D"Address" =
abstract=3D"false"=20
lazy=3D"false" discriminator-value=3D"Address" =
table=3D"`cmr3605t`"&gt;<BR><BR>I end=20
up with this mess when I relate the objects&nbsp; (-530 means invalid =
foreign=20
key value.&nbsp; Basically, it doesn't know how to map the relationships =
and=20
puts a bad value into the jdbc=20
statement):<BR>------------------------<BR>2007/07/12 15:38:32:551 PDT =
[DEBUG]=20
SQL - /* insert RelatedConsumer */ insert into "cmr3602t" (e_id, =
"isd_lock_ct",=20
"consumer_sk", "related_cmr_sk",=20
"cmr_relate_cd" ,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp ;&nbsp;&nbsp;=20
"relate_start_dt", "relate_end_dt", "isd_lupd_id", econtainer_class,=20
e_container, e_container_featureid, "dtype") values (default, ?, ?, ?, =
?, ?, ?,=20
?, ?, ?, ?, 'RelatedConsumer')<BR>2007/07/12 15:38:32:566 PDT [DEBUG]=20
AbstractBatcher - about to close PreparedStatement (open =
PreparedStatements: 1,=20
globally: 1)<BR>2007/07/12 15:38:32:582 PDT [DEBUG] =
JDBCExceptionReporter -=20
could not insert: [RelatedConsumer] [/* insert RelatedConsumer */ insert =
into=20
"cmr3602t" (e_id, "isd_lock_ct", "consumer_sk", "related_cmr_sk",=20
"cmr_relate_cd", "relate_start_dt", "relate_end_dt", "isd_lupd_id",=20
econtainer_class, e_container, e_container_featureid, "dtype") values =
(default,=20
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'RelatedConsumer')]=20
&lt;com.ibm.db2.jcc.b.SqlException: DB2 SQL error: SQLCODE: -530, =
SQLSTATE:=20
23503, SQLERRMC:=20
DB2ADMIN.cmr3602t.FK778C01274EE35F59&gt;com.ibm.db2.jcc. b.SqlException: =
DB2 SQL=20
error: SQLCODE: -530, SQLSTATE: 23503, SQLERRMC:=20
DB2ADMIN.cmr3602t.FK778C01274EE35F59<BR>2007/07/12 15:38:32:582 PDT =
[WARN]=20
JDBCExceptionReporter - SQL Error: -530, SQLState: 23503<BR>2007/07/12=20
15:38:32:582 PDT [ERROR] JDBCExceptionReporter - DB2 SQL error: SQLCODE: =
-530,=20
SQLSTATE: 23503, SQLERRMC:=20
DB2ADMIN.cmr3602t.FK778C01274EE35F59<BR>org.hibernate.exception.Constrain=
tViolationException:=20
could not insert: [RelatedConsumer]<BR>at=20
org.hibernate.exception.SQLStateConverter.convert(SQLStateCo nverter.java:=
71)<BR>at=20
org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExce ptionHelper.j=
ava:43)<BR>at=20
org.hibernate.id.insert.AbstractReturningDelegate.performIns ert(AbstractR=
eturningDelegate.java:40)<BR>at=20
org.hibernate.persister.entity.AbstractEntityPersister.inser t(AbstractEnt=
ityPersister.java:2158)<BR>at=20
org.hibernate.persister.entity.AbstractEntityPersister.inser t(AbstractEnt=
ityPersister.java:2638)<BR>at=20
org.hibernate.action.EntityIdentityInsertAction.execute(Enti tyIdentityIns=
ertAction.java:48)<BR>-----------------------<BR><BR>I=20
solve this with this bit of code in EntityMapper.java:<BR><BR>private =
Element=20
createEntity(PAnnotatedEClass entity,<BR>&nbsp;&nbsp;&nbsp; =
&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; =
&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; =
&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp;InheritanceType inhStrategy, PAnnotatedEClass=20
superEntity,<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; =

&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; =
&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp;DiscriminatorValue dValue, Table table) {</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>&nbsp;&nbsp;...<BR></FONT><FONT =
face=3DArial=20
size=3D2>&nbsp;&nbsp;final Element target;</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>&nbsp;&nbsp;final String entityName =3D =

getHbmContext().getEntityName(eclass);<BR>&nbsp;&nbsp;final String =
isAbstractStr=20
=3D eclass.isAbstract() ? "true" : "false";<BR>&nbsp;&nbsp;if=20
(entity.isOnlyMapAsEntity()) {<BR> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
target =3D=20
getHbmContext().getCurrent().addElement(hbClassName);<BR>&nbsp;&nbsp;&nbs=
p;<BR>&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp;if (hasCompositeID(entity)) { // only for this =
specific=20
case<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; =
&nbsp;&nbsp;&nbsp;&nbsp;String foo=20
=3D=20
hbmContext.getInstanceClassName(entity.getAnnotatedEClass()) ; <BR>&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp; target.addAttribute("name", =
foo);<BR>&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;//--- hard =
code fix=20
for missing class files.<BR>&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp;else{&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp; =
&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp;&nbsp;//--- JJH<BR>&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; target.addAttribute("name",=20
entity.getAnnotatedEClass().getEPackage().getNsPrefix()+".impl. "+entity.g=
etEntity().getName()+"Impl");<BR>&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;//--- =
JJH<BR>&nbsp;&nbsp;&nbsp;=20
&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;... <BR></FONT></DIV>
<DIV><FONT face=3DArial size=3D2>I probably need to fix the name =
attribute in more=20
places than this, but doing it here makes all my code work.</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>=3D=3D OTHER POSSIBLE =
SOLUTIONS:<BR></FONT></DIV>
<DIV><FONT face=3DArial size=3D2>I thought about putting the package =
prefix that I=20
need into a property, but that's no fun because I'd have to change it =
every time=20
I ran another ecore file through.&nbsp; Ideally there should be =
something in the=20
ecore that would hold the package name, but it's not there.&nbsp; And =
since I=20
can specify any random value for ecore:package in the xsd I really need =
to have=20
the right string in order for things to match up at runtime.&nbsp; =
</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>I considered adding annotation to the =
basic schema=20
level, but the annotations only come through on the actual entity =
objects.&nbsp;=20
I didn't want to re-specify the package on every entity because that =
seems even=20
more redundant than using nsPrefix.</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>I also found nsPrefix being used in a =
somewhat=20
similar way in the existing teneo code here:</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>HibernateFeatureMapEntry:</FONT></DIV>
<DIV><FONT size=3D2><FONT face=3DCourier>&nbsp;/** Code copied from=20
FeatureMapUtil.EntryImpl */<BR>&nbsp;public String toString()=20
{<BR>&nbsp;&nbsp;&nbsp;String prefix =3D=20
eStructuralFeature.getEContainingClass().getEPackage().getNs Prefix(); <BR>=
&nbsp;=20
&nbsp;eStructuralFeature.getName();<BR>&nbsp;&nbsp; return (prefix !=3D =
null=20
&amp;&amp; prefix.length() !=3D 0 ? prefix + ":" +=20
eStructuralFeature.getName()<BR>&nbsp;&nbsp;&nbsp; &nbsp; :=20
eStructuralFeature.getName())<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + "=3D" =
+=20
getValue();<BR>&nbsp;}<BR></FONT></FONT></DIV>
<DIV><FONT size=3D2><FONT face=3DCourier>and in=20
QualifyingEClassNameStrategy</FONT></FONT></DIV>
<DIV><FONT size=3D2><FONT face=3DCourier></FONT></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2><FONT face=3DCourier>&nbsp;public String =
toUniqueName(EClass=20
eClass) {<BR>&nbsp;&nbsp;&nbsp;if (eClass =3D=3D null) {<BR>&nbsp;&nbsp; =

&nbsp;&nbsp;throw new IllegalArgumentException("EClass cannot be=20
null.");<BR>&nbsp;&nbsp;&nbsp;}<BR>&nbsp; &nbsp;if (eClass =3D=3D =
EOBJECT_ECLASS)=20
{<BR>&nbsp;&nbsp;&nbsp; &nbsp;return=20
EOBJECT_ECLASS_NAME;<BR>&nbsp;&nbsp;&nbsp;}<BR >&nbsp; &nbsp;String =
nsPrefix =3D=20
eClass.getEPackage().getNsPrefix();<BR>&nbsp;&nbsp; if (nsPrefix =3D=3D =
null)=20
{<BR>&nbsp;&nbsp;&nbsp;&nbsp; nsPrefix =3D=20
eClass.getEPackage().getName();<BR>&nbsp;&nbsp;&nbsp;} <BR>&nbsp; =
&nbsp;return=20
nsPrefix + "." + =
eClass.getName();<BR>&nbsp;}<BR></FONT></DIV></FONT ><FONT=20
face=3DArial size=3D2>
<DIV>Not quite the same, but close enough that it seemed like a =
reasonable=20
fit.&nbsp; </DIV>
<DIV>I'm completely open to any other solution you might suggest.</DIV>
<DIV>&nbsp;</DIV>
<DIV>Remember that both of these problems do not exist if you're letting =
teneo=20
run when the classes are available.&nbsp; Its only when you run =
GenerateHBM=20
against an ecore with no other input and then force teneo to use that =
HBM that=20
you run into these troubles.</DIV>
<DIV>&nbsp;</DIV>
<DIV>Talk to you soon,</DIV>
<DIV>&nbsp;</DIV>
<DIV> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
Jason </DIV>
<DIV>&nbsp;</DIV>
<DIV>&nbsp;</DIV>
<DIV>&nbsp;</DIV>
<DIV></FONT>&nbsp;</DIV></BODY></HTML>

------=_NextPart_000_00E9_01C7C4A0.7B3D87F0--
Re: [ Teneo ] SDO class name problem [message #608741 is a reply to message #89649] Fri, 13 July 2007 07:07 Go to previous message
Martin Taal is currently offline Martin TaalFriend
Messages: 5468
Registered: July 2009
Senior Member
Hi Jason,
Does your enum value type implement EEnumLiteral?

How does the hbm look like for the second problem?

You can also send the ecore file to me so I can try this second issue.

The part of the code where you refer to where Teneo also uses the nsprefix is to create a unique
name for an EClass, this name is not a class name but just a unique string (which can be converted
back to the EClass).

gr. Martin

Jason Henriksen wrote:
>
> I agree that nsPrefix isn't the prettiest thing in the world, but
> without the java package I run into these two problems:
>
> == PROBLEM 1:
> When I first applied the fix in CVS I started seeing the enumerated
> types fail. I got this hbm
> <type
> name="org.eclipse.emf.teneo.hibernate.mapping.DynamicENumUserType ">
> <param name="eclassifier">RelationshipCodeType</param>
> <param name="epackage">http://vsp.com/</param>
> </type>
> Instead of the runtime generated hbm which looks like this:
> <type name="org.eclipse.emf.teneo.hibernate.mapping.ENumUserType" >
> <param
> name="enumClass">com.vsp.consumer.RelationshipCodeType</param >
> </type>
>
> The basic problem is that it tries cast DynamicENumUserType to the
> specific enumation type that I've defined, but that it doesn't know
> about from the ecore. Here's the exception:
>
> java.lang.ClassCastException: com.vsp.consumer.GenderCodeType
> Hibernate: /* insert Consumer */ insert into "cmr3601t" ("isd_lock_ct",
> "consumer_id", "name_prefix", "first_name", "middle_initial",
> "last_name", "name_suffix", "ssn", "date_of_birth", "gender_cd",
> "marital_status_cd", "citizenship_ind", "disability_ind",
> "ethnicity_cd", "other_id", "other_id_type_cd", "personal_info",
> "place_of_birth", "prefer_comm_method", "isd_lupd_id", econtainer_class,
> e_container, e_container_featureid, "dtype", "consumer_sk") values (?,
> ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
> 'Consumer', ?)
> at
> org.eclipse.emf.teneo.hibernate.mapping.DynamicENumUserType. nullSafeSet(DynamicENumUserType.java:137)
> at org.hibernate.type.CustomType.nullSafeSet(CustomType.java:14 6)
> at
> org.hibernate.persister.entity.AbstractEntityPersister.dehyd rate(AbstractEntityPersister.java:1997)
> at
> org.hibernate.persister.entity.AbstractEntityPersister.inser t(AbstractEntityPersister.java:2243)
> I solve this by altering AbstractMapper like this:
>
> private void handleEnumType(PAnnotatedEAttribute paAttribute, Element
> propElement) {
> final Enumerated enumerated = paAttribute.getEnumerated();
> assert (enumerated != null);
> final EAttribute eattr = paAttribute.getAnnotatedEAttribute();
> final EClassifier eclassifier = eattr.getEType();
> if (!getHbmContext().isGeneratedByEMF()
> && getHbmContext().getInstanceClass(eclassifier) != null) {
> final Class<?> instanceClass =
> getHbmContext().getInstanceClass(eclassifier);
> propElement.addElement("type").addAttribute("name",
> getEnumUserType(enumerated))
> .addElement("param").addAttribute("name",
> HbMapperConstants.ENUM_CLASS_PARAM)
> .addText(instanceClass.getName());
> } else if (getHbmContext().isGeneratedByEMF() &&
> eclassifier.getInstanceClass() != null) {
> propElement.addElement("type").addAttribute("name",
> getEnumUserType(enumerated))
> .addElement("param").addAttribute("name",
> HbMapperConstants.ENUM_CLASS_PARAM)
> .addText(eclassifier.getInstanceClass().getName());
> }
> //--- JJH
> else if (true) { // would be a property
>
> // brute force this to behave by letting the user specify what
> package should be used.
> // If this is not enabled, enumerations are treated as the wrong type.
> // This is ONLY needed if you are generating .hbm directly from
> .ecore without using annotated class files.
> String packageName = eclassifier.getEPackage().getNsPrefix();
> propElement..addElement("type").addAttribute("name",
> getEnumUserType(enumerated))
> .addElement("param").addAttribute("name",
> HbMapperConstants.ENUM_CLASS_PARAM)
> .addText(packageName+"."+eclassifier.getName());
> }
> //--- JJH
> else { // must be emf dynamic
> final Element typeElement =
> propElement.addElement("type").addAttribute("name",
> hbDynamicEnumType(enumerated));
> typeElement.addElement("param").addAttribute("name",
> HbMapperConstants.ECLASSIFIER_PARAM).addText(eclassifier.get Name());
> typeElement.addElement("param").addAttribute("name",
> HbMapperConstants.EPACKAGE_PARAM)
> .addText(eclassifier.getEPackage().getNsURI());
> }
>
> }
>
> == PROBLEM 2:
> So if I fix the CCE above with that bit of hardcoding and still let the
> output hbm look like this:
> <class entity-name="Address" abstract="false" lazy="false"
> discriminator-value="Address" table="`cmr3605t`">
> instead of how it should look as in this example:
> <class name="com.vsp.consumer.impl.AddressImpl"
> entity-name="Address" abstract="false" lazy="false"
> discriminator-value="Address" table="`cmr3605t`">
>
> I end up with this mess when I relate the objects (-530 means invalid
> foreign key value. Basically, it doesn't know how to map the
> relationships and puts a bad value into the jdbc statement):
> ------------------------
> 2007/07/12 15:38:32:551 PDT [DEBUG] SQL - /* insert RelatedConsumer */
> insert into "cmr3602t" (e_id, "isd_lock_ct", "consumer_sk",
> "related_cmr_sk", "cmr_relate_cd", "relate_start_dt",
> "relate_end_dt", "isd_lupd_id", econtainer_class, e_container,
> e_container_featureid, "dtype") values (default, ?, ?, ?, ?, ?, ?, ?, ?,
> ?, ?, 'RelatedConsumer')
> 2007/07/12 15:38:32:566 PDT [DEBUG] AbstractBatcher - about to close
> PreparedStatement (open PreparedStatements: 1, globally: 1)
> 2007/07/12 15:38:32:582 PDT [DEBUG] JDBCExceptionReporter - could not
> insert: [RelatedConsumer] [/* insert RelatedConsumer */ insert into
> "cmr3602t" (e_id, "isd_lock_ct", "consumer_sk", "related_cmr_sk",
> "cmr_relate_cd", "relate_start_dt", "relate_end_dt", "isd_lupd_id",
> econtainer_class, e_container, e_container_featureid, "dtype") values
> (default, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'RelatedConsumer')]
> <com.ibm.db2.jcc.b.SqlException: DB2 SQL error: SQLCODE: -530, SQLSTATE:
> 23503, SQLERRMC:
> DB2ADMIN.cmr3602t.FK778C01274EE35F59>com.ibm.db2.jcc.b.SqlException: DB2
> SQL error: SQLCODE: -530, SQLSTATE: 23503, SQLERRMC:
> DB2ADMIN.cmr3602t.FK778C01274EE35F59
> 2007/07/12 15:38:32:582 PDT [WARN] JDBCExceptionReporter - SQL Error:
> -530, SQLState: 23503
> 2007/07/12 15:38:32:582 PDT [ERROR] JDBCExceptionReporter - DB2 SQL
> error: SQLCODE: -530, SQLSTATE: 23503, SQLERRMC:
> DB2ADMIN.cmr3602t.FK778C01274EE35F59
> org.hibernate.exception.ConstraintViolationException: could not insert:
> [RelatedConsumer]
> at
> org.hibernate.exception.SQLStateConverter.convert(SQLStateCo nverter.java:71)
> at
> org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExce ptionHelper.java:43)
> at
> org.hibernate.id.insert.AbstractReturningDelegate.performIns ert(AbstractReturningDelegate.java:40)
> at
> org.hibernate.persister.entity.AbstractEntityPersister.inser t(AbstractEntityPersister.java:2158)
> at
> org.hibernate.persister.entity.AbstractEntityPersister.inser t(AbstractEntityPersister.java:2638)
> at
> org.hibernate.action.EntityIdentityInsertAction.execute(Enti tyIdentityInsertAction.java:48)
> -----------------------
>
> I solve this with this bit of code in EntityMapper.java:
>
> private Element createEntity(PAnnotatedEClass entity,
> InheritanceType inhStrategy,
> PAnnotatedEClass superEntity,
> DiscriminatorValue dValue,
> Table table) {
>
> ...
> final Element target;
>
> final String entityName = getHbmContext().getEntityName(eclass);
> final String isAbstractStr = eclass.isAbstract() ? "true" : "false";
> if (entity.isOnlyMapAsEntity()) {
> target = getHbmContext().getCurrent().addElement(hbClassName);
>
> if (hasCompositeID(entity)) { // only for this specific case
> String foo =
> hbmContext.getInstanceClassName(entity.getAnnotatedEClass()) ;
> target.addAttribute("name", foo);
> }
> //--- hard code fix for missing class files.
> else{
> //--- JJH
> target.addAttribute("name",
> entity.getAnnotatedEClass().getEPackage().getNsPrefix()+".impl. "+entity.getEntity().getName()+"Impl");
> //--- JJH
> }
> ...
> I probably need to fix the name attribute in more places than this, but
> doing it here makes all my code work.
>
> == OTHER POSSIBLE SOLUTIONS:
> I thought about putting the package prefix that I need into a property,
> but that's no fun because I'd have to change it every time I ran another
> ecore file through. Ideally there should be something in the ecore that
> would hold the package name, but it's not there. And since I can
> specify any random value for ecore:package in the xsd I really need to
> have the right string in order for things to match up at runtime.
>
> I considered adding annotation to the basic schema level, but the
> annotations only come through on the actual entity objects. I didn't
> want to re-specify the package on every entity because that seems even
> more redundant than using nsPrefix.
>
> I also found nsPrefix being used in a somewhat similar way in the
> existing teneo code here:
>
> HibernateFeatureMapEntry:
> /** Code copied from FeatureMapUtil.EntryImpl */
> public String toString() {
> String prefix =
> eStructuralFeature.getEContainingClass().getEPackage().getNs Prefix();
> eStructuralFeature.getName();
> return (prefix != null && prefix.length() != 0 ? prefix + ":" +
> eStructuralFeature.getName()
> : eStructuralFeature.getName())
> + "=" + getValue();
> }
> and in QualifyingEClassNameStrategy
>
> public String toUniqueName(EClass eClass) {
> if (eClass == null) {
> throw new IllegalArgumentException("EClass cannot be null.");
> }
> if (eClass == EOBJECT_ECLASS) {
> return EOBJECT_ECLASS_NAME;
> }
> String nsPrefix = eClass.getEPackage().getNsPrefix();
> if (nsPrefix == null) {
> nsPrefix = eClass.getEPackage().getName();
> }
> return nsPrefix + "." + eClass.getName();
> }
> Not quite the same, but close enough that it seemed like a reasonable fit.
> I'm completely open to any other solution you might suggest.
>
> Remember that both of these problems do not exist if you're letting
> teneo run when the classes are available. Its only when you run
> GenerateHBM against an ecore with no other input and then force teneo to
> use that HBM that you run into these troubles.
>
> Talk to you soon,
>
> Jason
>
>
>
>


--

With Regards, Martin Taal

Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
Previous Topic:[EMF Compare] NullViewer opening
Next Topic:[EMF Compare] XSLT File
Goto Forum:
  


Current Time: Thu Apr 18 06:41:58 GMT 2024

Powered by FUDForum. Page generated in 0.03542 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top