openjpa-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Vermeulen (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (OPENJPA-2375) generate predictable names for primary and foreign keys
Date Wed, 24 Apr 2013 11:13:15 GMT

    [ https://issues.apache.org/jira/browse/OPENJPA-2375?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13640343#comment-13640343
] 

Vermeulen commented on OPENJPA-2375:
------------------------------------

Here's what I already tried:

The most obvious way to implement this is by using the openjpa.jdbc.MappingDefaults property
to set a custom MappingDefaults strategy. So I extended PersistenceMappingDefaults and have
overridden getForeignKey(ValueMapping, DBIdentifier, Table, Table, boolean) getJoinForeignKey
to set the foreign key identifier to 

DBIdentifier.preCombine(DBIdentifier.combine(table.getIdentifier(), refersTo.getName()), "FK")

This actually works nicely. However the method getPrimaryKeyIdentifier(ClassMapping, Table)
is never called. It does seem to be called when using the option DefaultMissingInfo=false.
However I get an exception where it cannot handle a @MappedSuperclass that has a generated
primary key column:

org.apache.openjpa.util.MetaDataException: For "nl.hm.olga.core.entity.AbstractEntity.id",
expected 1 column(s), but found 0.

So I am using DefaultMissingInfo = true.
After inspecting OpenJPA's code I found a workaround hack. The PK is created in OpenJPA class
FullClassStrategy. Somehow the boolean adapt is set to false with DefaultMissingInfo = true.
I extended this class and copy/pasted the code of the map method and always enabled the line
that gets the PK identifier:

pkname =
						cls.getMappingRepository().getMappingDefaults()
								.getPrimaryKeyIdentifier(cls, table);

This custom extended class can be used by setting this configuration in persistence.xml:
			<property name="openjpa.jdbc.MappingDefaults"
				value="nl.hm.olga.core.dao.openjpa.KeyConstraintNamesMappingDefaults(ForeignKeyDeleteAction=restrict,
JoinForeignKeyDeleteAction=restrict, 
				BaseClassStrategy=org.apache.openjpa.jdbc.meta.strats.PrimaryKeyConstraintNameFullClassStrategy)"
/>

However this introduces a bug: I am using inheritance with @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
and this strategy is overwritten by the base class strategy resulting in tables for the abstract
superclass that otherwise wouldn't exist. It also doesn't work as the SubclassStrategy for
openjpa.jdbc.MappingDefaults

I found out the hard way that BaseClassStrategy and SubclassStrategy are null by default.
This is not clear from the documentation; it even states that flat is the default strategy
which I verified to be false: an appropriate strategy is selected based on configuration on
the entities. Using these settings will ignore the individual settings in the entities and
use the strategies for all entities.
(This feels similar to when the Java switch statement would always execute the default case
if it is present....)

Lesson learned: don't mess with OpenJPA internals and be very careful with custom plugin strategies.

Even though I got it mostly working I'm giving up because it's so dangerous. Will look into
a SQL only way.
                
> generate predictable names for primary and foreign keys
> -------------------------------------------------------
>
>                 Key: OPENJPA-2375
>                 URL: https://issues.apache.org/jira/browse/OPENJPA-2375
>             Project: OpenJPA
>          Issue Type: Improvement
>          Components: jdbc
>    Affects Versions: 2.2.1
>            Reporter: Vermeulen
>
> When the MappingTool creates the database schema, OpenJPA will let the database determine
the names of primary and foreign key constraints. Microsoft SQL server uses a seemingly random
number which changes each time the database schema is generated. This makes it harder to create
SQL scripts that refer to these keys or use schema comparison tools.
> Names of generated keys could e.g. be:
> PK_<table name>
> FK_<table name>_<referenced foreign column name>
> (Perhaps adding foreign table name as well to prevent possible name clashes)

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

Mime
View raw message