Mapping in Kodo 3
Am I correct in my impression that in Kodo 3 all mapping related
extensions that could formerly have been done in the *.jdo file via Kodo
entensions (table=, size= ordered=, etc.) can now be done in the mapping
file or are there exceptions?
Scott
Am I correct in my impression that in Kodo 3 all mapping related
extensions that could formerly have been done in the *.jdo file via Kodo
entensions (table=, size= ordered=, etc.) can now be done in the mapping
file or are there exceptions?No. Currently, only mapping data can go in the .mapping file. This
does not inlcude things like column sizes, index attributes, etc. It
only includes the mapping of classes and fields to tables and columns.
In the future, we plan on supporting additional mapping formats, in
particular JDO 2 metadata, which allows you to separate out all
schema+mapping information, or to include it all in your main JDO file,
all without needing extensions.
Similar Messages
-
Reverse Mapping: letting Kodo manage pk-column
Hi again,
i have a db with many predefined tables. Its not allowed to change the db
schema. The generated Java-classes are looking fine but i want to let kodo
manage the pk columns (like JDOIDX in generated tables). I dont want the
more technical pks in my business classes. Is it possible?
Any help is welcome!Abe White wrote:
Adding a data store identity option to the reverse mapping tool is relatively
high on our to-do list, but it's not implemented yet. For now, you can
follow the steps in the documentation for reverse-mapping your classes, then
switch over to datastore identity manually by changing the class definitions
and metadata.Ok, this solution is workable. Will try it, thanks! -
3.1.4 reverse mapping tool issue
(Sorry for the duplicate posting...I meant to start a new thread with
this but accidentally posted it as a reply to a 6-month old thread)
Hello,
I was running Kodo 3.0.2 when Abe and I had the exchange reproduced
below back in January to deal with Oracle tables with "$" in the column
names (which I subsequently updated to 3.0.3). The original subject of
this discussion was "3.0.2 reverse mapping tool generates invalid
..mapping file".
I was able to get this working by running the following commands to
implement Abe's suggestion:
reversemappingtool -p kodo.properties -package db \
-cp custom.properties -ds false schema.xml
sed -e 's/\$/__DOLLAR__/' db/package.mapping > db/package.mapping.new
mv db/package.mapping.new db/package.mapping
javac db/*.java
mappingtool -p kodo.properties -a import db/package.mapping
sed -e 's/__DOLLAR__/\$/' db/package.jdo > db/package.jdo.new
mv db/package.jdo.new db/package.jdo
In my custom.properties file, I had lines like these to put useful names
on my class's fields:
db.TransactionDetailHistory.y$an8.rename : addressNumber
As I said, in 3.0.3, this worked perfectly.
I picked this code back up for the first time since getting it working 6
months ago, and decided to update it to 3.1.4 (since I'm already using
that on other projects). Problem is, the reverse mapping tool has
changed and the code it generates no longer works as it once did. I
tried running the 3.1.2 and 3.1.0 reverse mapping tool, and it failed
the same way, so it looks like this change happened in the 3.0.x to
3.1.x version change.
What happens is this: In the generated Java source, my fields used to
end up with names as per my specification (e.g., the Oracle column named
"y$an8" showed up as "addressNumber" in the java source).
However, it looks like the "$" became special somehow in 3.1.0 - the
"y$an8" column now shows up as "yAn8" in the generated Java. I tried
changing my custom.properties file accordingly, but it still shows up as
yAn8 even after changing my mapping to look like this:
db.TransactionDetailHistory.yAn8.rename : addressNumber
What do you make of this?
Thanks,
Bill
Abe White wrote:
> Hmmm... this is a problem. '$' is not legal in XML names, and there
is no standard way to escape it.
>
> Your best bet is probably to do the following:
> 1. In the generated .mapping file, replace all '$' characters with
another token, such as '--DOLLAR--'.
> 2. Switch your properties to use the metadata mapping factory:
> kodo.jdbc.MappingFactory: metadata
> 3. Import your mappings into the metadata mapping factory:
> mappingtool -a import package.mapping
> 4. Delete the mapping file.
> 5. In your .jdo file, replace '--DOLLAR--' with '$' again.
>
> The metadata mapping factory doesn't put column names in its XML
attribute names, so you should be able to use it safely.William-
However, it looks like the "$" became special somehow in 3.1.0 - the
"y$an8" column now shows up as "yAn8" in the generated Java. I tried
changing my custom.properties file accordingly, but it still shows up as
yAn8 even after changing my mapping to look like this:
db.TransactionDetailHistory.yAn8.rename : addressNumberWell, the reverse mapping tool makes some assumptions based on common
naming strategies for relational databases and Java naming: columns like
"FIRST_NAME" will be renamed to "firstName". The Reverse Mapping tool is
seeing the "$" and treating it as a non-alphanumeric delimiter, so is
fixing it.
Can you try a couple of additional properties:
db.TransactionDetailHistory.y$An8.rename: addressNumber
db.TransactionDetailHistory.y$an8.rename: addressNumber
Also, are other rename properties working for you, or is that the only
field or class you attempt to rename? It might just be the case that
you aren't correctly specifying the properties file or something.
Finally, bear in mind that you can always implement your own
kodo.jdbc.meta.ReverseCustomizer and just use that; not the easiest
solution, but it can certainly be used to have very fine-grained control
over the exact names that are generated.
In article <[email protected]>, William Korb wrote:
(Sorry for the duplicate posting...I meant to start a new thread with
this but accidentally posted it as a reply to a 6-month old thread)
Hello,
I was running Kodo 3.0.2 when Abe and I had the exchange reproduced
below back in January to deal with Oracle tables with "$" in the column
names (which I subsequently updated to 3.0.3). The original subject of
this discussion was "3.0.2 reverse mapping tool generates invalid
.mapping file".
I was able to get this working by running the following commands to
implement Abe's suggestion:
reversemappingtool -p kodo.properties -package db \
-cp custom.properties -ds false schema.xml
sed -e 's/\$/__DOLLAR__/' db/package.mapping > db/package.mapping.new
mv db/package.mapping.new db/package.mapping
javac db/*.java
mappingtool -p kodo.properties -a import db/package.mapping
sed -e 's/__DOLLAR__/\$/' db/package.jdo > db/package.jdo.new
mv db/package.jdo.new db/package.jdo
In my custom.properties file, I had lines like these to put useful names
on my class's fields:
db.TransactionDetailHistory.y$an8.rename : addressNumber
As I said, in 3.0.3, this worked perfectly.
I picked this code back up for the first time since getting it working 6
months ago, and decided to update it to 3.1.4 (since I'm already using
that on other projects). Problem is, the reverse mapping tool has
changed and the code it generates no longer works as it once did. I
tried running the 3.1.2 and 3.1.0 reverse mapping tool, and it failed
the same way, so it looks like this change happened in the 3.0.x to
3.1.x version change.
What happens is this: In the generated Java source, my fields used to
end up with names as per my specification (e.g., the Oracle column named
"y$an8" showed up as "addressNumber" in the java source).
However, it looks like the "$" became special somehow in 3.1.0 - the
"y$an8" column now shows up as "yAn8" in the generated Java. I tried
changing my custom.properties file accordingly, but it still shows up as
yAn8 even after changing my mapping to look like this:
db.TransactionDetailHistory.yAn8.rename : addressNumber
What do you make of this?
Thanks,
Bill
Abe White wrote:
Hmmm... this is a problem. '$' is not legal in XML names, and thereis no standard way to escape it.
Your best bet is probably to do the following:
1. In the generated .mapping file, replace all '$' characters withanother token, such as '--DOLLAR--'.
2. Switch your properties to use the metadata mapping factory:
kodo.jdbc.MappingFactory: metadata
3. Import your mappings into the metadata mapping factory:
mappingtool -a import package.mapping
4. Delete the mapping file.
5. In your .jdo file, replace '--DOLLAR--' with '$' again.
The metadata mapping factory doesn't put column names in its XMLattribute names, so you should be able to use it safely.--
Marc Prud'hommeaux
SolarMetric Inc. -
Kodo extensions in orm.xml?
I'm evaluating Kodo for use with JPA, but I would like to use externalized mapping files. These work fine for standard "to the spec" mappings, but I'd like to be able to use some of the Kodo-specific extensions (such as custom field handlers). Is this possible within an externalized JPA mapping file (e.g. orm.xml)? All of the docs that I have found for Kodo JPA use annotations.
"Amol" <[email protected]> writes:
I have been going thru mails in the newsgrp, for help in my work and I
found a lot of extensions used (r they only kodo-specific). I have gone
thru all of the documentation tht comes with 2.2 release but havent a
documentation for this extensions. Where can i find them.The JDO standard defines a syntax for adding vendor-specific metadata to
the JDO metadata files. So yes, the extensions that you are referring to
are Kodo-specific.
Most of our vendor extensions are used for controlling the
object-relational mapping that Kodo performs.
Look in the metadata and existing schema sections of the 2.2.2
documentation for more information on possible extensions. The 2.2.3
documentation is formatted slightly differently; it contains an appendix
with a list of all extensions supported by Kodo.
-Patrick
Patrick Linskey [email protected]
SolarMetric Inc. http://www.solarmetric.com -
I have been going thru mails in the newsgrp, for help in my work and I
found a lot of extensions used (r they only kodo-specific). I have gone
thru all of the documentation tht comes with 2.2 release but havent a
documentation for this extensions. Where can i find them.
Amol."Amol" <[email protected]> writes:
I have been going thru mails in the newsgrp, for help in my work and I
found a lot of extensions used (r they only kodo-specific). I have gone
thru all of the documentation tht comes with 2.2 release but havent a
documentation for this extensions. Where can i find them.The JDO standard defines a syntax for adding vendor-specific metadata to
the JDO metadata files. So yes, the extensions that you are referring to
are Kodo-specific.
Most of our vendor extensions are used for controlling the
object-relational mapping that Kodo performs.
Look in the metadata and existing schema sections of the 2.2.2
documentation for more information on possible extensions. The 2.2.3
documentation is formatted slightly differently; it contains an appendix
with a list of all extensions supported by Kodo.
-Patrick
Patrick Linskey [email protected]
SolarMetric Inc. http://www.solarmetric.com -
CustomClassMappings . Some observations
I looked into custom class mappings example and would like to share some my
thoughts. I might easily miss some points since all I have is this example
so please correct me if I am wrong. I also realize that field level custom
mappings can be done to large extent inside of PC itself.
I feel that the process is too much "all or nothing" - custom mappings have
to replace Kodo default mappings entirely (no way to add/modify/use kodo
built in mappings). As result
- No field level custom mappings
- No inheritance (each class in a hierarch has to provide its own mapping)
- no JDOQL on entire class
It would be nice to add some sort of custom mappings on field level rather
than only class level. It will allow to handle a case when only one or more
fields should be custom mapped while generation of entire
select/update/delete/insert statements can be left to kodo (as long as
custom field mapping gives kodo something to put into prepared statement
param) and all JDOQ logic (except possibly custom mapped fields if field
mapping does not support it) is preserved.
Example - field of oracle object typeAlex, can you share how you did the custom mapping on a particular field
only?
This is exactly what I want to do (map a java field to a postgresql
size(col) function)
"Alex Roytman" <[email protected]> wrote in message
news:b3cb8k$7k4$[email protected]..
After doing some more research I found Field mapping including collection
fields.
Now I do not need to provide mapping for entire class just for fields Iwant
custom mapped. Great!
"Alex Roytman" <[email protected]> wrote in message
news:b3bkge$tdm$[email protected]..
I looked into custom class mappings example and would like to share somemy
thoughts. I might easily miss some points since all I have is this
example
so please correct me if I am wrong. I also realize that field levelcustom
mappings can be done to large extent inside of PC itself.
I feel that the process is too much "all or nothing" - custom mappingshave
to replace Kodo default mappings entirely (no way to add/modify/use kodo
built in mappings). As result
- No field level custom mappings
- No inheritance (each class in a hierarch has to provide its own
mapping)
- no JDOQL on entire class
It would be nice to add some sort of custom mappings on field levelrather
than only class level. It will allow to handle a case when only one ormore
fields should be custom mapped while generation of entire
select/update/delete/insert statements can be left to kodo (as long as
custom field mapping gives kodo something to put into prepared
statement
param) and all JDOQ logic (except possibly custom mapped fields if field
mapping does not support it) is preserved.
Example - field of oracle object type -
Horizontal mapping not working in Kodo 4.1.2
Hello,
I am having troubles in trying to get the class mapping I want in Kodo 4.1.2.
I want to go from Kodo 3.3 to Kodo 4.1, and still in the evaluation process. Basically, all I want is to have my package.jdo files to work in Kodo 4.1, with the minimum modifications, before moving to JPA.
The mapping is defined is my package.jdo using the <extension vendor-name="kodo" key="jdbc-class-map" value="XXX"/> where XXX can be one of horizontal, base or flat (I dont use vertical in this applicaion). This element does not seem to be properly recognized by the new mapping tool, and all my classes are mapped in the same base table.
After some digging in the docs and in the examples provided, I found this <inheritance strategy="XXX"/> element, that can be put in my package.jdo file. This is not clearly said in the docs (it seems this element is only mentionned in the new orm DTD), but is used in the sample/jdo/horizontal/package.jdo file.
Then I modified my package.jdo files, with this new element, where XXX is one of subclass-table, new-table (with no <join/> nested element) or superclass-table. But the result is not the one expected : all the classes are mapped in the same table.
I then gave a try at the example provided, compiled, enhanced and mapped the sample/jdo/horizontal classes provided with the distribution, since this example covers exactly what I want to do. It seems to me that this example does not work either.
The package.jdo says :
<jdo>
<package name="samples.jdo.horizontal">
<sequence name="sjvm" factory-class="sjvm" strategy="nontransactional"/>
<class name="LastModified">
<inheritance strategy="subclass-table"/>
</class>
The mapping file I get says :
<mapping>
<package name="samples.jdo.horizontal">
<class name="LastModified">
<jdbc-class-map type="base" pk-column="ID" table="LASTMODIFIED"/>
<jdbc-version-ind type="version-number" column="VERSN"/>
<jdbc-class-ind type="in-class-name" column="TYP"/>
<field name="creationDate">
<jdbc-field-map type="value" column="CREATIONDATE"/>
</field>
<field name="lastModificationDate">
<jdbc-field-map type="value" column="LASTMODIFICATIONDATE"/>
</field>
</class>
The enhancement is made using jdoc, the mapping file is generated using the following command line (the DB is empty) :
mappingtool -a refresh -f mapping.xml samples.jdo.horizontal.LastModifiedI would expect an horizontal mapping, with a class element containing only a <jdbc-class-map type="horizontal"/> element, as it is the case if I use my Kodo 3.3 mapping tool.
I tried the enhancement / mapping file generation process with two configuration of the kodo.properties file : the first one with kodo3 as the Mapping Factory and the second with jdo. The result is the same in both cases. I verified by setting the log level to TRACE for the Tool what the factory used. In fact in both case, it is the MappingFileDeprecatedJDOMappingFactory, which seems weird to me.
Bytheway, setting the MappingFactory to jpa leads to the following IllegalArgumentException during enhancement :
Exception in thread "main" org.apache.openjpa.lib.util.ParseException: Instantiation of plugin "MetaDataFactory" with value "jpa" caused an error "java.lang.IllegalArgumentException : java.lang.ClassNotFoundException: jpa". The alias or class name may have been misspelled, or the class may not have be available in the class path. Valid aliases for this plugin are: [jdo, kodo3]
I'd be glad to get any hint if I'm wrong on anything, or any workaround / patch to get my case to work.
Thank you in advance,
JoseIf the same exact app and code works with 4.0 with the same ForeignKeyDeleteAction setting, I suggest that you open a case with support.
This property hasn't changed since 4.0
http://e-docs.bea.com/kodo/docs41/full/html/ref_guide_mapping_defaults.html
Laurent -
Relational queries through JDBC with the help of Kodo's metadata for O/R mapping
Due to JDOQL's limitations (inability to express joins, when relationships
are not modeled as object references), I find myself needing to drop down to
expressing some queries in SQL through JDBC. However, I still want my Java
code to remain independent of the O/R mapping. I would like to be able to
formulate the SQL without hardcoding any knowledge of the relational table
and column names, by using Kodo's metadata. After poking around the Kodo
Javadocs, it appears as though the relevant calls are as follows:
ClassMetaData cmd = ClassMetaData.getInstance(MyPCObject.class, pm);
FieldMetaData fmd = cmd.getDeclaredField( "myField" );
PersistenceManagerFactory pmf = pm.getPersistenceManagerFactory();
JDBCConfiguration conf = (JDBCConfiguration)
((EEPersistenceManagerFactory)pmf).getConfiguration();
ClassResolver resolver = pm.getClassResolver(MyPCObject.class);
Connector connector = new PersistenceManagerConnector(
(PersistenceManagerImpl) pm );
DBDictionary dict = conf.getDictionary( connector );
FieldMapping fm = ClassMapping.getFieldMapping(fmd, conf, resolver, dict);
Column[] cols = fm.getDataColumns();
Does that look about right?
Here's what I'm trying to do:
class Foo
String name; // application identity
String bar; // foreign key to Bar
class Bar
String name; // application identity
int weight;
Let's say I want to query for all Foo instances for which its bar.weight >
100. Clearly this is trivial to do in JDOQL, if Foo.bar is an object
reference to Bar. But there are frequently good reasons for modeling
relationships as above, for example when Foo and Bar are DTOs exposed by the
remote interface of an EJB. (Yeah, yeah, I'm lazy, using my
PersistenceCapable classes as both the DAOs and the DTOs.) But I still want
to do queries that navigate the relationship; it would be nice to do it in
JDOQL directly. I will also want to do other weird-ass queries that would
definitely only be expressible in SQL. Hence, I'll need Kodo's O/R mapping
metadata.
Is there anything terribly flawed with this logic?
BenI have a one point before I get to this:
There is nothing wrong with using PC instances as both DAO and DTO
objects. In fact, I strongly recommend this for most J2EE/JDO design.
However, there should be no need to expose the foreign key values... use
application identity to quickly reconstitute an object id (which can in
turn find the persistent version), or like the j2ee tutorial, store the
object id in some form (Object or String) and use that to re-find the
matching persistent instance at the EJB tier.
Otherwise, there is a much easier way of finding ClassMapping instances
and in turn FieldMapping instances (see ClassMapping.getInstance () in
the JavaDocs).
Ben Eng wrote:
Due to JDOQL's limitations (inability to express joins, when relationships
are not modeled as object references), I find myself needing to drop down to
expressing some queries in SQL through JDBC. However, I still want my Java
code to remain independent of the O/R mapping. I would like to be able to
formulate the SQL without hardcoding any knowledge of the relational table
and column names, by using Kodo's metadata. After poking around the Kodo
Javadocs, it appears as though the relevant calls are as follows:
ClassMetaData cmd = ClassMetaData.getInstance(MyPCObject.class, pm);
FieldMetaData fmd = cmd.getDeclaredField( "myField" );
PersistenceManagerFactory pmf = pm.getPersistenceManagerFactory();
JDBCConfiguration conf = (JDBCConfiguration)
((EEPersistenceManagerFactory)pmf).getConfiguration();
ClassResolver resolver = pm.getClassResolver(MyPCObject.class);
Connector connector = new PersistenceManagerConnector(
(PersistenceManagerImpl) pm );
DBDictionary dict = conf.getDictionary( connector );
FieldMapping fm = ClassMapping.getFieldMapping(fmd, conf, resolver, dict);
Column[] cols = fm.getDataColumns();
Does that look about right?
Here's what I'm trying to do:
class Foo
String name; // application identity
String bar; // foreign key to Bar
class Bar
String name; // application identity
int weight;
Let's say I want to query for all Foo instances for which its bar.weight >
100. Clearly this is trivial to do in JDOQL, if Foo.bar is an object
reference to Bar. But there are frequently good reasons for modeling
relationships as above, for example when Foo and Bar are DTOs exposed by the
remote interface of an EJB. (Yeah, yeah, I'm lazy, using my
PersistenceCapable classes as both the DAOs and the DTOs.) But I still want
to do queries that navigate the relationship; it would be nice to do it in
JDOQL directly. I will also want to do other weird-ass queries that would
definitely only be expressible in SQL. Hence, I'll need Kodo's O/R mapping
metadata.
Is there anything terribly flawed with this logic?
Ben
Steve Kim
[email protected]
SolarMetric Inc.
http://www.solarmetric.com -
WS 3.2, Kodo 4, JPA mapping of CLOB
The problem that I have is related to JPA CLOB mapping. Underlying oracle table has a CLOB field. DbXplorer correctly recognize the type of the column as CLOB but when I generate JPA mapping for the table, the CLOB column is mapped to Object without @Lob annotation.
<i>
private Object payload;
@Basic()
@Column(name="PAYLOAD", length=4000)
public Object getPayload() {
return this.payload;
public void setPayload(Object payload) {
this.payload = payload;
</i>
Such a class is compiled but not ENHANCED (I opened .class file in editor and it did not implemented kodo.enhance.PeristenceCapable). No errors at all. When I manually added @Lob() annotation and changed Object to String, it was enhanced, but when I read the data, CLOB field was ‘null’ and the rest of columns populated with correct data. I updated such an object with a new data and it was written to database. The next read was the same – gived me a ‘null’ value for CLOB field.
Am I missing something? Please help.Download the latest 10g oracle jdbc driver (supports 9.2 database), mapping still DOES NOT work (doesn't generate @Lob annotation but java.sql.Clob object), running is OK.
-
Table mapping (KODO 3.4) using XDoclet
Hi,
I need to map an Object to a differntly named table via XDoclet. That is described in the [url http://edocs.bea.com/kodo/docs303/ref_guide_integration_xdoclet.html]Docs here.
When I use the foloowing class it will produce a different looking JDO file and KODO simply ignores it. Can you tell me, what I'm doing wrong?
Java Code:
* @jdo.persistence-capable
* identity-type="application"
* objectid-class="MyClassId"
* @jdo.class-vendor-extension
* vendor-name="kodo" key="detachable" value="true"
* @jdo.class-vendor-extension
* vendor-name="kodo" key="jdbc-class-map" value="base"
* @jdo.class-vendor-extension
* vendor-name="kodo" key="jdbc-class-map/table" value="MyTableName"
public class MyClass {...}
JDO file:
<class name="MyClass" identity-type="application" objectid-class="MyClassId" requires-extent="true">
<extension vendor-name="kodo" key="detachable" value="true">
</extension>
<extension vendor-name="kodo" key="jdbc-class-map" value="base">
</extension>
<extension vendor-name="kodo" key="jdbc-class-map/table" value="MyTableName">
</extension>
<field name="xxx" persistence-modifier="persistent" primary-key="false" null-value="none">
</field>
Update:
I also tried:
* @jdo.persistence-capable
* identity-type="application"
* objectid-class="MyClassId"
* table="MyTable"
public class MyClass {...}
But it seems, Kodo does not support the table attribute!
Update 2:
The upper solution should be the right one. It seems in the kodo.properties must be set the attribute "kodo.jdbc.MappingFactory: metadata"
Is anyone using such a table mapping that is working? I'm still struggeling to get this working!
Edited by jdeluxe at 05/16/2008 4:32 AMWow, I didn't expect almost 100 people watching this thread without any hint!
Here it is:
Ant Task
<jdomappingtool action="refresh" sqlfile="XXX">
<fileset dir="YYY" >
<include name="**/*.jdo" />
</fileset>
<config propertiesFile="D:/kodo-jdo-3.4.1/kodo.properties" />
EntityClass:
* @jdo.persistence-capable
* identity-type="application"
* objectid-class="foo.MyClassId"
* name="myClass"
* @jdo.class-vendor-extension
* vendor-name="kodo" key="jdbc-class-map" value="base"
* @jdo.class-vendor-extension
* vendor-name="kodo" key="jdbc-class-map/table" value="MYTABLENAME"
* @jdo.class-vendor-extension
* vendor-name="kodo" key="jdbc-class-map/pk-column" value="ID"
public class MyClass {
* description
* @jdo.field persistence-modifier="persistent"
* @jdo.field-vendor-extension vendor-name="kodo"
* key="jdbc-field-map" value="value"
* @jdo.field-vendor-extension vendor-name="kodo"
* key="jdbc-field-map/column" value="description"
private String description;
Note that when not using the explicit column mapping I experienced a strange behaviour: Kodo did not map to the existing table column, but wanted to add new fields postfixed with "1" (e.g. ALTER TABLE MYTABLENAME ADD COLUMN "description1").
Also the setting
kodo.jdbc.MappingFactory: metadata
in the kodo.properties file is mandatory !!!!! -
Unit test fails after upgrading to Kodo 4.0.0 from 4.0.0-EA4
I have a group of 6 unit tests failing after upgrading to the new Kodo
4.0.0 (with BEA) from Kodo-4.0.0-EA4 (with Solarmetric). I'm getting
exceptions like the one at the bottom of this email. It seems to be an
interaction with the PostgreSQL driver, though I can't be sure. I
haven't changed my JDO configuration or the related classes in months
since I've been focusing on using the objects that have already been
defined. The .jdo, .jdoquery, and .java code are below the exception,
just in case there's something wrong in there. Does anyone have advice
as to how I might debug this?
Thanks,
Mark
Testsuite: edu.ucsc.whisper.test.integration.UserManagerQueryIntegrationTest
Tests run: 15, Failures: 0, Errors: 6, Time elapsed: 23.308 sec
Testcase:
testGetAllUsersWithFirstName(edu.ucsc.whisper.test.integration.UserManagerQueryIntegrationTest):
Caused an ERROR
The column index is out of range: 2, number of columns: 1.
<2|false|4.0.0> kodo.jdo.DataStoreException: The column index is out of
range: 2, number of columns: 1.
at
kodo.jdbc.sql.DBDictionary.newStoreException(DBDictionary.java:4092)
at kodo.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:82)
at kodo.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:66)
at kodo.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:46)
at
kodo.jdbc.kernel.SelectResultObjectProvider.handleCheckedException(SelectResultObjectProvider.java:176)
at
kodo.kernel.QueryImpl$PackingResultObjectProvider.handleCheckedException(QueryImpl.java:2460)
at
com.solarmetric.rop.EagerResultList.<init>(EagerResultList.java:32)
at kodo.kernel.QueryImpl.toResult(QueryImpl.java:1445)
at kodo.kernel.QueryImpl.execute(QueryImpl.java:1136)
at kodo.kernel.QueryImpl.execute(QueryImpl.java:901)
at kodo.kernel.QueryImpl.execute(QueryImpl.java:865)
at kodo.kernel.DelegatingQuery.execute(DelegatingQuery.java:787)
at kodo.jdo.QueryImpl.executeWithArray(QueryImpl.java:210)
at kodo.jdo.QueryImpl.execute(QueryImpl.java:137)
at
edu.ucsc.whisper.core.dao.JdoUserDao.findAllUsersWithFirstName(JdoUserDao.java:232)
at
edu.ucsc.whisper.core.manager.DefaultUserManager.getAllUsersWithFirstName(DefaultUserManager.java:252)
NestedThrowablesStackTrace:
org.postgresql.util.PSQLException: The column index is out of range: 2,
number of columns: 1.
at
org.postgresql.core.v3.SimpleParameterList.bind(SimpleParameterList.java:57)
at
org.postgresql.core.v3.SimpleParameterList.setLiteralParameter(SimpleParameterList.java:101)
at
org.postgresql.jdbc2.AbstractJdbc2Statement.bindLiteral(AbstractJdbc2Statement.java:2085)
at
org.postgresql.jdbc2.AbstractJdbc2Statement.setInt(AbstractJdbc2Statement.java:1133)
at
com.solarmetric.jdbc.DelegatingPreparedStatement.setInt(DelegatingPreparedStatement.java:390)
at
com.solarmetric.jdbc.PoolConnection$PoolPreparedStatement.setInt(PoolConnection.java:440)
at
com.solarmetric.jdbc.DelegatingPreparedStatement.setInt(DelegatingPreparedStatement.java:390)
at
com.solarmetric.jdbc.DelegatingPreparedStatement.setInt(DelegatingPreparedStatement.java:390)
at
com.solarmetric.jdbc.DelegatingPreparedStatement.setInt(DelegatingPreparedStatement.java:390)
at
com.solarmetric.jdbc.LoggingConnectionDecorator$LoggingConnection$LoggingPreparedStatement.setInt(LoggingConnectionDecorator.java:1
257)
at
com.solarmetric.jdbc.DelegatingPreparedStatement.setInt(DelegatingPreparedStatement.java:390)
at
com.solarmetric.jdbc.DelegatingPreparedStatement.setInt(DelegatingPreparedStatement.java:390)
at kodo.jdbc.sql.DBDictionary.setInt(DBDictionary.java:980)
at kodo.jdbc.sql.DBDictionary.setUnknown(DBDictionary.java:1299)
at kodo.jdbc.sql.SQLBuffer.setParameters(SQLBuffer.java:638)
at kodo.jdbc.sql.SQLBuffer.prepareStatement(SQLBuffer.java:539)
at kodo.jdbc.sql.SQLBuffer.prepareStatement(SQLBuffer.java:512)
at kodo.jdbc.sql.SelectImpl.execute(SelectImpl.java:332)
at kodo.jdbc.sql.SelectImpl.execute(SelectImpl.java:301)
at kodo.jdbc.sql.Union$UnionSelect.execute(Union.java:642)
at kodo.jdbc.sql.Union.execute(Union.java:326)
at kodo.jdbc.sql.Union.execute(Union.java:313)
at
kodo.jdbc.kernel.SelectResultObjectProvider.open(SelectResultObjectProvider.java:98)
at
kodo.kernel.QueryImpl$PackingResultObjectProvider.open(QueryImpl.java:2405)
at
com.solarmetric.rop.EagerResultList.<init>(EagerResultList.java:22)
at kodo.kernel.QueryImpl.toResult(QueryImpl.java:1445)
at kodo.kernel.QueryImpl.execute(QueryImpl.java:1136)
at kodo.kernel.QueryImpl.execute(QueryImpl.java:901)
at kodo.kernel.QueryImpl.execute(QueryImpl.java:865)
at kodo.kernel.DelegatingQuery.execute(DelegatingQuery.java:787)
at kodo.jdo.QueryImpl.executeWithArray(QueryImpl.java:210)
at kodo.jdo.QueryImpl.execute(QueryImpl.java:137)
at
edu.ucsc.whisper.core.dao.JdoUserDao.findAllUsersWithFirstName(JdoUserDao.java:232)
--- DefaultUser.java -------------------------------------------------
public class DefaultUser
implements User
/** The account username. */
private String username;
/** The account password. */
private String password;
/** A flag indicating whether or not the account is enabled. */
private boolean enabled;
/** The authorities granted to this account. */
private Set<Authority> authorities;
/** Information about the user, including their name and text that
describes them. */
private UserInfo userInfo;
/** The set of organizations where this user works. */
private Set<Organization> organizations;
--- DefaultUser.jdo --------------------------------------------------
<?xml version="1.0"?>
<!DOCTYPE jdo PUBLIC
"-//Sun Microsystems, Inc.//DTD Java Data Objects Metadata 2.0//EN"
"http://java.sun.com/dtd/jdo_2_0.dtd">
<jdo>
<package name="edu.ucsc.whisper.core">
<sequence name="user_id_seq"
factory-class="native(Sequence=user_id_seq)"/>
<class name="DefaultUser" detachable="true"
table="whisper_user" identity-type="datastore">
<datastore-identity sequence="user_id_seq" column="userId"/>
<field name="username">
<column name="username" length="80" jdbc-type="VARCHAR" />
</field>
<field name="password">
<column name="password" length="40" jdbc-type="CHAR" />
</field>
<field name="enabled">
<column name="enabled" />
</field>
<field name="userInfo" persistence-modifier="persistent"
default-fetch-group="true" dependent="true">
<extension vendor-name="jpox"
key="implementation-classes"
value="edu.ucsc.whisper.core.DefaultUserInfo" />
<extension vendor-name="kodo"
key="type"
value="edu.ucsc.whisper.core.DefaultUserInfo" />
</field>
<field name="authorities" persistence-modifier="persistent"
table="user_authorities"
default-fetch-group="true">
<collection
element-type="edu.ucsc.whisper.core.DefaultAuthority" />
<join column="userId" delete-action="cascade"/>
<element column="authorityId" delete-action="cascade"/>
</field>
<field name="organizations" persistence-modifier="persistent"
table="user_organizations" mapped-by="user"
default-fetch-group="true" dependent="true">
<collection
element-type="edu.ucsc.whisper.core.DefaultOrganization"
dependent-element="true"/>
<join column="userId"/>
<!--<element column="organizationId"/>-->
</field>
</class>
</package>
</jdo>
--- DefaultUser.jdoquery ---------------------------------------------
<?xml version="1.0"?>
<!DOCTYPE jdo PUBLIC
"-//Sun Microsystems, Inc.//DTD Java Data Objects Metadata 2.0//EN"
"http://java.sun.com/dtd/jdo_2_0.dtd">
<jdo>
<package name="edu.ucsc.whisper.core">
<class name="DefaultUser">
<query name="UserByUsername"
language="javax.jdo.query.JDOQL"><![CDATA[
SELECT UNIQUE FROM edu.ucsc.whisper.core.DefaultUser
WHERE username==searchName
PARAMETERS java.lang.String searchName
]]></query>
<query name="DisabledUsers"
language="javax.jdo.query.JDOQL"><![CDATA[
SELECT FROM edu.ucsc.whisper.core.DefaultUser WHERE
enabled==false
]]></query>
<query name="EnabledUsers"
language="javax.jdo.query.JDOQL"><![CDATA[
SELECT FROM edu.ucsc.whisper.core.DefaultUser WHERE
enabled==true
]]></query>
<query name="CountUsers"
language="javax.jdo.query.JDOQL"><![CDATA[
SELECT count( this ) FROM edu.ucsc.whisper.core.DefaultUser
]]></query>
</class>
</package>
</jdo>I'm sorry, I have no idea. I suggest sending a test case that
reproduces the problem to support. -
Reverse Mapping Tutorial - Finder.java queries the wrong table?!
I have been almost successful in running the Reverse Mapping Tutorial, by
creating Java Classes from the hsqldb sample database, and running the JDO
Enhancer on them.
However, I cannot get he Finder.java to work. It seems to look in the wrong
table: MAGAZINEX instead of MAGAZINE?
Did anyone have trouble with this step, or ran it successfully?
Liviu
PS: here is the trace:
0 [main] INFO kodo.Runtime - Starting Kodo JDO version 2.4.2
(kodojdo-2.4.2-20030326-1841) with capabilities: [Enterprise Edition
Features, Standard Edition Features, Lite Edition Features, Evaluation
License, Query Extensions, Datacache Plug-in, Statement Batching, Global
Transactions, Developer Tools, Custom Database Dictionaries, Enterprise
Databases]
70 [main] WARN kodo.Runtime - WARNING: Kodo JDO Evaluation expires in 25
days. Please contact [email protected] for information on extending your
evaluation period or purchasing a license.
68398 [main] INFO kodo.MetaData -
com.solarmetric.kodo.meta.JDOMetaDataParser@19eda2c: parsing source:
file:/C:/Documents%20and%20Settings/default/jbproject/JDO/classes/reversetut
orial.jdo
74577 [main] INFO jdbc.JDBC - [ C:24713456; T:31737213; D:22310332 ] open:
jdbc:hsqldb:hsql_sample_database (sa)
75689 [main] INFO jdbc.JDBC - [ C:24713456; T:31737213; D:22310332 ] close:
com.solarmetric.datasource.PoolConnection@17918f0[[requests=0;size=0;max=70;
hits=0;created=0;redundant=0;overflow=0;new=0;leaked=0;unavailable=0]]
75699 [main] INFO jdbc.JDBC - [ C:24713456; T:31737213; D:22310332 ] close
connection
77331 [main] INFO jdbc.JDBC - Using dictionary class
"com.solarmetric.kodo.impl.jdbc.schema.dict.HSQLDictionary" to connect to
"HSQL Database Engine" (version "1.7.0") with JDBC driver "HSQL Database
Engine Driver" (version "1.7.0")
1163173 [main] INFO jdbc.JDBC - [ C:3093871; T:31737213; D:22310332 ] open:
jdbc:hsqldb:hsql_sample_database (sa)
1163293 [main] INFO jdbc.SQL - [ C:3093871; T:31737213; D:22310332 ]
preparing statement <17940412>: SELECT DISTINCT MAGAZINEX.JDOCLASSX FROM
MAGAZINEX
1163313 [main] INFO jdbc.SQL - [ C:3093871; T:31737213; D:22310332 ]
executing statement <17940412>: [reused=1;params={}]
1163443 [main] INFO jdbc.JDBC - [ C:3093871; T:31737213; D:22310332 ]
close:
com.solarmetric.datasource.PoolConnection@2f356f[[requests=1;size=0;max=70;h
its=0;created=1;redundant=0;overflow=0;new=1;leaked=0;unavailable=0]]
1163443 [main] INFO jdbc.JDBC - [ C:3093871; T:31737213; D:22310332 ] close
connection
Hit uncaught exception javax.jdo.JDOFatalDataStoreException
javax.jdo.JDOFatalDataStoreException:
com.solarmetric.kodo.impl.jdbc.sql.SQLExceptionWrapper:
[SQL=SELECT DISTINCT MAGAZINEX.JDOCLASSX FROM MAGAZINEX]
[PRE=SELECT DISTINCT MAGAZINEX.JDOCLASSX FROM MAGAZINEX]
Table not found: S0002 Table not found: MAGAZINEX in statement [SELECT
DISTINCT MAGAZINEX.JDOCLASSX FROM MAGAZINEX] [code=-22;state=S0002]
NestedThrowables:
com.solarmetric.kodo.impl.jdbc.sql.SQLExceptionWrapper:
[SQL=SELECT DISTINCT MAGAZINEX.JDOCLASSX FROM MAGAZINEX]
[PRE=SELECT DISTINCT MAGAZINEX.JDOCLASSX FROM MAGAZINEX]
Table not found: S0002 Table not found: MAGAZINEX in statement [SELECT
DISTINCT MAGAZINEX.JDOCLASSX FROM MAGAZINEX]
at
com.solarmetric.kodo.impl.jdbc.runtime.SQLExceptions.throwFatal(SQLException
s.java:17)
at
com.solarmetric.kodo.impl.jdbc.ormapping.SubclassProviderImpl.getSubclasses(
SubclassProviderImpl.java:283)
at
com.solarmetric.kodo.impl.jdbc.ormapping.ClassMapping.getPrimaryMappingField
s(ClassMapping.java:1093)
at
com.solarmetric.kodo.impl.jdbc.runtime.JDBCStoreManager.executeQuery(JDBCSto
reManager.java:704)
at
com.solarmetric.kodo.impl.jdbc.runtime.JDBCQuery.executeQuery(JDBCQuery.java
:93)
at com.solarmetric.kodo.query.QueryImpl.executeWithMap(QueryImpl.java:792)
at com.solarmetric.kodo.query.QueryImpl.execute(QueryImpl.java:595)
at reversetutorial.Finder.main(Finder.java:32)
NestedThrowablesStackTrace:
java.sql.SQLException: Table not found: S0002 Table not found: MAGAZINEX in
statement [SELECT DISTINCT MAGAZINEX.JDOCLASSX FROM MAGAZINEX]
at org.hsqldb.Trace.getError(Trace.java:226)
at org.hsqldb.jdbcResultSet.<init>(jdbcResultSet.java:6595)
at org.hsqldb.jdbcConnection.executeStandalone(jdbcConnection.java:2951)
at org.hsqldb.jdbcConnection.execute(jdbcConnection.java:2540)
at org.hsqldb.jdbcStatement.fetchResult(jdbcStatement.java:1804)
at org.hsqldb.jdbcStatement.executeQuery(jdbcStatement.java:199)
at
org.hsqldb.jdbcPreparedStatement.executeQuery(jdbcPreparedStatement.java:391
at
com.solarmetric.datasource.PreparedStatementWrapper.executeQuery(PreparedSta
tementWrapper.java:93)
at
com.solarmetric.kodo.impl.jdbc.SQLExecutionManagerImpl.executePreparedQueryI
nternal(SQLExecutionManagerImpl.java:771)
at
com.solarmetric.kodo.impl.jdbc.SQLExecutionManagerImpl.executeQueryInternal(
SQLExecutionManagerImpl.java:691)
at
com.solarmetric.kodo.impl.jdbc.SQLExecutionManagerImpl.executeQuery(SQLExecu
tionManagerImpl.java:372)
at
com.solarmetric.kodo.impl.jdbc.SQLExecutionManagerImpl.executeQuery(SQLExecu
tionManagerImpl.java:356)
at
com.solarmetric.kodo.impl.jdbc.ormapping.SubclassProviderImpl.getSubclasses(
SubclassProviderImpl.java:246)
at
com.solarmetric.kodo.impl.jdbc.ormapping.ClassMapping.getPrimaryMappingField
s(ClassMapping.java:1093)
at
com.solarmetric.kodo.impl.jdbc.runtime.JDBCStoreManager.executeQuery(JDBCSto
reManager.java:704)
at
com.solarmetric.kodo.impl.jdbc.runtime.JDBCQuery.executeQuery(JDBCQuery.java
:93)
at com.solarmetric.kodo.query.QueryImpl.executeWithMap(QueryImpl.java:792)
at com.solarmetric.kodo.query.QueryImpl.execute(QueryImpl.java:595)
at reversetutorial.Finder.main(Finder.java:32)The reason I did not run importtool is because ... I actually ran it, but it
was not successfull. **!
I now tried the solutions directory, from the kodo distribution, and that
failed as well. Here is what I did:
- I went to reversetutorial/solutions, and compiled all the classes, and
then placed them into a reversetutorial folder (to match the package)
- ran "rd-importtool reversetutorial.mapping" (the mapping file from the
solutions directory), which failed as below:
0 [main] INFO kodo.MetaData - Parsing metadata resource
"file:/C:/kodo/reversetutorial/solutions/reversetutorial.mapping".
Exception in thread "main"
com.solarmetric.rd.kodo.meta.JDOMetaDataNotFoundException: No JDO metadata
was found for type "class reversetutorial.Article".
FailedObject:class reversetutorial.Article
at
com.solarmetric.rd.kodo.meta.JDOMetaDataRepositoryImpl.getMetaData(JDOMetaDa
taRepositoryImpl.java:148)
at
com.solarmetric.rd.kodo.impl.jdbc.meta.MappingRepository.getMetaData(Mapping
Repository.java:147)
at
com.solarmetric.rd.kodo.impl.jdbc.meta.MappingRepository.getMapping(MappingR
epository.java:158)
at
com.solarmetric.rd.kodo.impl.jdbc.meta.compat.ImportTool.getMapping(ImportTo
ol.java:126)
at
com.solarmetric.rd.kodo.impl.jdbc.meta.compat.ImportTool.importMappings(Impo
rtTool.java:57)
at
com.solarmetric.rd.kodo.impl.jdbc.meta.compat.ImportTool.run(ImportTool.java
:408)
at
com.solarmetric.rd.kodo.impl.jdbc.meta.compat.ImportTool.main(ImportTool.jav
a:385)
Any idea why? The solutions directory should work, right? I even tried
specifying a kodo.properties file, but it did not seem to help.
Liviu
"Abe White" <[email protected]> wrote in message
news:[email protected]...
Running the reversemappingtool creates classes, metadata files, and a
.mapping file. That .mapping file contains all the O/R mapping
information for how the generated classes map to your existing database
tables. What the importtool does is just transfer that mapping
information to the metadata files, in the form of <extension> elements.
The reason this is a separate step will be clear once Kodo 3.0 comes out.
So in sum, the importtool does not affect the database in any way. It
just moves information from one format (.mapping file) to another
(<extension> elements in the .jdo file). -
How to use a MAP whithout join table
Hello
I am still evaluating KODO ;-)
I am using kodo 3.1.2 with an evaluation version
linux (kernel 2.6)
SUN JDK 1.4.2_04
MYSQL MAX 4.0.18 -Max
IDEA 4.0.3 and ANT 1.5.4 (to be exhaustive)
I am wondering how to configure the following mapping involving a Map. :
public class Translation {
private String locale;
private String txt;
public class TranslatableDescription {
/**Map of Key=locale as String; Value = {@link Translation}*/
==> private Map translations = new HashMap(); <==
public void addATranslation(Translation t){
translations.put(t.getLocale(), t);
file package.jdo :
<?xml version="1.0"?>
<jdo>
<package name="data">
<class name="Translation"/>
<class name="TranslatableDescription">
<field name="translations">
<map key-type="java.lang.String"
value-type="tutorial.data.Translation"/>
<extension vendor-name="kodo" key="jdbc-key-size" value="10"/>
</field>
</class>
</package>
</jdo>
The default Mapping generate a join table : TRANS_TRANSLATION which works
fine, but I would like to remove this table by adding a
colonne in the "TRANSLATION" table containing the JDOID of the
TRANSLATIONDESCRIPTION owner of this TRANSLATION.
I have made some try like this one in the mapping file
<class name="TranslatableDescription">
<field name="translations">
<jdbc-field-map type="n-many-map" key-column="LOCALE"
ref-column.JDOID="OWNERJDOID" table="TRANSLATION0"
value-column.JDOID="JDOID"/>
</field>
The schema generated in my DB is correct but when I try to persist some
objects I have the following Exception :
727 INFO [main] kodo.jdbc.JDBC - Using dictionary class
"kodo.jdbc.sql.MySQLDictionary" (MySQL 4.0.18'-Max' ,MySQL-AB JDBC Driver
mysql-connector-java-3.0.10-stable ( $Date: 2004/01/13 21:56:18 $,
$Revision: 1.27.2.33 $ )).
Exception in thread "main" kodo.util.FatalDataStoreException: Invalid
argument value, message from server: "Duplicate entry '2' for key 1"
{prepstmnt 8549963 INSERT INTO TRANSLATION0 (JDOID, LOCALESTR, OWNERJDOID)
VALUES (?, ?, ?) [reused=0]} [code=1062, state=S1009]
NestedThrowables:
com.solarmetric.jdbc.ReportingSQLException: Invalid argument value,
message from server: "Duplicate entry '2' for key 1" {prepstmnt 8549963
INSERT INTO TRANSLATION0 (JDOID, LOCALESTR, OWNERJDOID) VALUES (?, ?, ?)
[reused=0]} [code=1062, state=S1009]
java.sql.BatchUpdateException: Invalid argument value, message from
server: "Duplicate entry '2' for key 1"
at kodo.jdbc.sql.SQLExceptions.getFatalDataStore(SQLExceptions.java:42)
at kodo.jdbc.sql.SQLExceptions.getFatalDataStore(SQLExceptions.java:24)
at kodo.jdbc.runtime.JDBCStoreManager.flush(JDBCStoreManager.java:594)
at
kodo.runtime.DelegatingStoreManager.flush(DelegatingStoreManager.java:152)
at
kodo.runtime.PersistenceManagerImpl.flushInternal(PersistenceManagerImpl.java:964)
at
kodo.runtime.PersistenceManagerImpl.beforeCompletion(PersistenceManagerImpl.java:813)
at kodo.runtime.LocalManagedRuntime.commit(LocalManagedRuntime.java:69)
at
kodo.runtime.PersistenceManagerImpl.commit(PersistenceManagerImpl.java:542)
at
tutorial.CreateTranslatableDescription.main(CreateTranslatableDescription.java:48)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at com.intellij.rt.execution.application.AppMain.main(Unknown Source)
I have the feeling that KODO does try to make diffent row in the table
"TRANSLATION0" for the TRANSLATION and the MAP.
So, is this kind of mapping supported by KODO and if yes, how can I
configure it.
Thank you for your help
NicolasSo, is this kind of mapping supported by KODO and if yes, how can I
configure it.It is not directly supported. You can fake it using a one-many mapping
(see thread: Externalizing Map to Collection of PC), but unless you must
map to an existing schema, it's probably not worth the effort. (Note:
also there is a bug that actually prevents this from working with 3.1.2;
the bug is fixed for 3.1.3, but it hasn't been released yet). -
Mapping tool creates new columns one at a time
Hi All,
I'm using Kodo 3.2.2 with MySql 4.1. I have a fairly large table (over
2million rows) representing one persistent class. I need to add several
new fields to the object, which will require a refresh mapping on the
database to add new columns for the fields.
It seems when I run refresh mapping on the database, Kodo is adding each
new field individually in seperate ALTER TABLE statements, rather than
adding all the columns in one ALTER TABLE statement.
With MySQL and large tables, this can really increase the time required to
refresh the mapping - I've tried with MSSQL and that database must handle
ALTER TABLE commands differently because it doesn't take a fraction of the
time that MySQL takes.
Is this a bug (I doubt it), but rather a feature improvement?
Thoughts?
Thanks,
BrendanThanks Abe for the reply - I've been meaning to look at the process of
creating SQL scripts to perform the refresh mappings on our databases.
I'll have a look at this process before we talk contracting!
Thanks,
Brendan
Abe White wrote:
Unfortunately, we don't have any immediate plans to optimize ALTER TABLEsince
it's not a runtime operation, and as you say most DBs don't have a problemwith
it. Also, note that the documentation shows how to get Kodo to create SQL
scripts rather than directly modify the DB; you could easily edit thescripts
Kodo generates to make them more efficient before piping the SQL to MySQLusing
its client app. (Note that Kodo 3.3 introduces the ability to generate SQL
scripts directly from the mapping tool, rather than having to take an extrastep
through the schema tool).
If getting Kodo to combine ALTER statements is important to you, you couldalso
contact [email protected] about contracting us to expedite this work. -
Caching problem w/ primary-foreign key mapping
I have seen this a couple of times now. It is not consistent enough to
create a simple reproducible test case, so I will have to describe it to you
with an example and hope you can track it down. It only occurs when caching
is enabled.
Here are the classes:
class C1 { int id; C2 c2; }
class C2 { int id; C1 c1; }
Each class uses application identity using static nested Id classes: C1.Id
and C2.Id. What is unusual is that the same value is used for both
instances:
int id = nextId();
C1 c1 = new C1(id);
C2 c2 = new C2(id);
c1.c2 = c2;
c2.c1 = c1;
This all works fine using optimistic transactions with caching disabled.
Although the integer values are the same, the oids are unique because each
class defines its own unique oid class.
Here is the schema and mapping (this works with caching disabled but fails
with caching enabled):
table t1: column id integer, column revision integer, primary key (id)
table t2: column id integer, column revision integer, primary key (id)
<jdo>
<package name="test">
<class name="C1" objectid-class="C1$Id">
<extension vendor-name="kodo" key="jdbc-class-map" value="base">
<extension vendor-name="kodo" key="table" value="t1"/>
</extension>
<extension vendor-name="kodo" key="jdbc-version-ind"
value="version-number">
<extension vendor-name="kodo" key="column" value="revision"/>
</extension>
<field name="id" primary-key="true">
<extension vendor-name="kodo" key="jdbc-field-map" value="value">
<extension vendor-name="kodo" key="column" value="id"/>
</extension>
</field>
<field name="c2">
<extension vendor-name="kodo" key="jdbc-field-map" value="one-one">
<extension vendor-name="kodo" key="column.id" value="id"/>
</extension>
</field>
</class>
<class name="C2" objectid-class="C2$Id">
<extension vendor-name="kodo" key="jdbc-class-map" value="base">
<extension vendor-name="kodo" key="table" value="t2"/>
</extension>
<extension vendor-name="kodo" key="jdbc-version-ind"
value="version-number">
<extension vendor-name="kodo" key="column" value="revision"/>
</extension>
<field name="id" primary-key="true">
<extension vendor-name="kodo" key="jdbc-field-map" value="value">
<extension vendor-name="kodo" key="column" value="id"/>
</extension>
</field>
<field name="c1">
<extension vendor-name="kodo" key="dependent" value="true"/>
<extension vendor-name="kodo" key="inverse-owner" value="c2"/>
<extension vendor-name="kodo" key="jdbc-field-map" value="one-one">
<extension vendor-name="kodo" key="table" value="t1"/>
<extension vendor-name="kodo" key="ref-column.id" value="id"/>
<extension vendor-name="kodo" key="column.id" value="id"/>
</extension>
</field>
</class>
</package>
</jdo>
Because the ids are known to be the same, the primary key values are also
used as foreign key values. Accessing C2.c1 is always non-null when caching
is disabled. With caching is enabled C2.c1 is usually non-null but sometimes
null. When it is null we get warnings about dangling references to deleted
instances with id values of 0 and other similar warnings.
The workaround is to add a redundant column with the same value. For some
reason this works around the caching problem (this is unnecessary with
caching disabled):
table t1: column id integer, column id2 integer, column revision integer,
primary key (id), unique index (id2)
table t2: column id integer, column revision integer, primary key (id)
<jdo>
<package name="test">
<class name="C1" objectid-class="C1$Id">
<extension vendor-name="kodo" key="jdbc-class-map" value="base">
<extension vendor-name="kodo" key="table" value="t1"/>
</extension>
<extension vendor-name="kodo" key="jdbc-version-ind"
value="version-number">
<extension vendor-name="kodo" key="column" value="revision"/>
</extension>
<field name="id" primary-key="true">
<extension vendor-name="kodo" key="jdbc-field-map" value="value">
<extension vendor-name="kodo" key="column" value="id"/>
</extension>
</field>
<field name="c2">
<extension vendor-name="kodo" key="jdbc-field-map" value="one-one">
<extension vendor-name="kodo" key="column.id" value="id2"/>
</extension>
</field>
</class>
<class name="C2" objectid-class="C2$Id">
<extension vendor-name="kodo" key="jdbc-class-map" value="base">
<extension vendor-name="kodo" key="table" value="t2"/>
</extension>
<extension vendor-name="kodo" key="jdbc-version-ind"
value="version-number">
<extension vendor-name="kodo" key="column" value="revision"/>
</extension>
<field name="id" primary-key="true">
<extension vendor-name="kodo" key="jdbc-field-map" value="value">
<extension vendor-name="kodo" key="column" value="id"/>
</extension>
</field>
<field name="c1">
<extension vendor-name="kodo" key="dependent" value="true"/>
<extension vendor-name="kodo" key="inverse-owner" value="c2"/>
<extension vendor-name="kodo" key="jdbc-field-map" value="one-one">
<extension vendor-name="kodo" key="table" value="t1"/>
<extension vendor-name="kodo" key="ref-column.id" value="id2"/>
<extension vendor-name="kodo" key="column.id" value="id"/>
</extension>
</field>
</class>
</package>
</jdo>
Needless to say, the extra column adds a lot of overhead, including the
addition of a second unique index, for no value other than working around
the caching defect.Tom-
The first thing that I think of whenever I see a problem like this is
that the equals() and hashCode() methods of your application identity
classes are not correct. Can you check them to ensure that they are
written in accordance to the guidelines at:
http://docs.solarmetric.com/manual.html#jdo_overview_pc_identity_application
If that doesn't help address the problem, can you post the code for your
application identity classes so we can double-check, and we will try to
determine what might be causing the problem.
In article <[email protected]>, Tom Landon wrote:
I have seen this a couple of times now. It is not consistent enough to
create a simple reproducible test case, so I will have to describe it to you
with an example and hope you can track it down. It only occurs when caching
is enabled.
Here are the classes:
class C1 { int id; C2 c2; }
class C2 { int id; C1 c1; }
Each class uses application identity using static nested Id classes: C1.Id
and C2.Id. What is unusual is that the same value is used for both
instances:
int id = nextId();
C1 c1 = new C1(id);
C2 c2 = new C2(id);
c1.c2 = c2;
c2.c1 = c1;
This all works fine using optimistic transactions with caching disabled.
Although the integer values are the same, the oids are unique because each
class defines its own unique oid class.
Here is the schema and mapping (this works with caching disabled but fails
with caching enabled):
table t1: column id integer, column revision integer, primary key (id)
table t2: column id integer, column revision integer, primary key (id)
<jdo>
<package name="test">
<class name="C1" objectid-class="C1$Id">
<extension vendor-name="kodo" key="jdbc-class-map" value="base">
<extension vendor-name="kodo" key="table" value="t1"/>
</extension>
<extension vendor-name="kodo" key="jdbc-version-ind"
value="version-number">
<extension vendor-name="kodo" key="column" value="revision"/>
</extension>
<field name="id" primary-key="true">
<extension vendor-name="kodo" key="jdbc-field-map" value="value">
<extension vendor-name="kodo" key="column" value="id"/>
</extension>
</field>
<field name="c2">
<extension vendor-name="kodo" key="jdbc-field-map" value="one-one">
<extension vendor-name="kodo" key="column.id" value="id"/>
</extension>
</field>
</class>
<class name="C2" objectid-class="C2$Id">
<extension vendor-name="kodo" key="jdbc-class-map" value="base">
<extension vendor-name="kodo" key="table" value="t2"/>
</extension>
<extension vendor-name="kodo" key="jdbc-version-ind"
value="version-number">
<extension vendor-name="kodo" key="column" value="revision"/>
</extension>
<field name="id" primary-key="true">
<extension vendor-name="kodo" key="jdbc-field-map" value="value">
<extension vendor-name="kodo" key="column" value="id"/>
</extension>
</field>
<field name="c1">
<extension vendor-name="kodo" key="dependent" value="true"/>
<extension vendor-name="kodo" key="inverse-owner" value="c2"/>
<extension vendor-name="kodo" key="jdbc-field-map" value="one-one">
<extension vendor-name="kodo" key="table" value="t1"/>
<extension vendor-name="kodo" key="ref-column.id" value="id"/>
<extension vendor-name="kodo" key="column.id" value="id"/>
</extension>
</field>
</class>
</package>
</jdo>
Because the ids are known to be the same, the primary key values are also
used as foreign key values. Accessing C2.c1 is always non-null when caching
is disabled. With caching is enabled C2.c1 is usually non-null but sometimes
null. When it is null we get warnings about dangling references to deleted
instances with id values of 0 and other similar warnings.
The workaround is to add a redundant column with the same value. For some
reason this works around the caching problem (this is unnecessary with
caching disabled):
table t1: column id integer, column id2 integer, column revision integer,
primary key (id), unique index (id2)
table t2: column id integer, column revision integer, primary key (id)
<jdo>
<package name="test">
<class name="C1" objectid-class="C1$Id">
<extension vendor-name="kodo" key="jdbc-class-map" value="base">
<extension vendor-name="kodo" key="table" value="t1"/>
</extension>
<extension vendor-name="kodo" key="jdbc-version-ind"
value="version-number">
<extension vendor-name="kodo" key="column" value="revision"/>
</extension>
<field name="id" primary-key="true">
<extension vendor-name="kodo" key="jdbc-field-map" value="value">
<extension vendor-name="kodo" key="column" value="id"/>
</extension>
</field>
<field name="c2">
<extension vendor-name="kodo" key="jdbc-field-map" value="one-one">
<extension vendor-name="kodo" key="column.id" value="id2"/>
</extension>
</field>
</class>
<class name="C2" objectid-class="C2$Id">
<extension vendor-name="kodo" key="jdbc-class-map" value="base">
<extension vendor-name="kodo" key="table" value="t2"/>
</extension>
<extension vendor-name="kodo" key="jdbc-version-ind"
value="version-number">
<extension vendor-name="kodo" key="column" value="revision"/>
</extension>
<field name="id" primary-key="true">
<extension vendor-name="kodo" key="jdbc-field-map" value="value">
<extension vendor-name="kodo" key="column" value="id"/>
</extension>
</field>
<field name="c1">
<extension vendor-name="kodo" key="dependent" value="true"/>
<extension vendor-name="kodo" key="inverse-owner" value="c2"/>
<extension vendor-name="kodo" key="jdbc-field-map" value="one-one">
<extension vendor-name="kodo" key="table" value="t1"/>
<extension vendor-name="kodo" key="ref-column.id" value="id2"/>
<extension vendor-name="kodo" key="column.id" value="id"/>
</extension>
</field>
</class>
</package>
</jdo>
Needless to say, the extra column adds a lot of overhead, including the
addition of a second unique index, for no value other than working around
the caching defect.
Marc Prud'hommeaux [email protected]
SolarMetric Inc. http://www.solarmetric.com
Maybe you are looking for
-
I am tying to hook up new ipods the we got for xmas and for some reason it just says that it in unable to connect to server. I am wondering if there is a limit of how many can be hooked up? we have an ipad, 1 working ipod and 2 previous ones that are
-
Problems with Spotlight searching of shared volumes
According to: http://www.apple.com/macosx/features/300.html#spotlight, I should be able to "...search any connected Mac with Personal File Sharing enabled or a file server that's sharing its files." It doesn't specify what "file server", so I presume
-
How to 'lock' my cursor to one of my two monitors?
Hello all, thanks for reading my question! My 'problem' is the following: I recently started using a second monitor on my iMac [OsX Yosemite - 10.10.2 / i5 - 2,7GHz / 8GB 1600MHz DD3]. The additional monitor is a Samsung 40" Television screen that I
-
Why are my programs glitching and everything become hidden until you hover over it
Over the past few days my adobe programs have been failing on me. layers and their details have become invisible and various menu buttons and text will disappear until you hover over it. I am not sure why this is happening and it is stressful when I
-
Can you skip the overview from HRMSS_A_CATS_APPROVAL
Hi all I would like to configure the WDA application HRMSS_A_CATS_APPROVAL using the application configuration HRMSS_AC_CATS_APPROVAL in such a way that it is only the detailed view that is used. The overview should be omitted entirely as the users a