Issue Details (XML | Word | Printable)

Key: NUCENHANCER-73
Type: Improvement Improvement
Status: Closed Closed
Resolution: Won't Fix
Priority: Minor Minor
Assignee: Unassigned
Reporter: subes
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
DataNucleus Enhancer (ARCHIVED)

jdoDetachedState picked up by Hibernate as a column

Created: 23/Apr/11 04:55 PM   Updated: 17/Jun/11 05:14 PM   Resolved: 24/Apr/11 07:40 AM
Component/s: None
Affects Version/s: 3.0.0.m3
Fix Version/s: None

Severity: Development


 Description  « Hide
DataNucleusEnhancer adds the following fields to a JPA @Entity:

protected transient StateManager jdoStateManager;
protected transient byte jdoFlags;
protected Object[] jdoDetachedState;
private static final byte[] jdoFieldFlags;
private static final Class jdoPersistenceCapableSuperclass;
private static final Class[] jdoFieldTypes;
private static final String[] jdoFieldNames = __jdoFieldNamesInit();
private static final int jdoInheritedFieldCount;

All are either static final or transient except for jdoDetachedState, which is nicely ignored by DataNucleus schema generation:
2011-04-23 14:29:22,612 [1|main ] DEBUG DataNucleus.Datastore.Schema.debug - CREATE TABLE "TestEntity"
(
    "id" BIGINT NOT NULL,
    "name" VARCHAR(255) NULL,
    "aktualisiert" TIMESTAMP NULL,
    "angelegt" TIMESTAMP NULL,
    "version" INTEGER NULL,
    CONSTRAINT "TestEntity_PK" PRIMARY KEY ("id")
)

But when running Hibernate with the enhanced Entity, the field is picked up and a Column is generated for it:
2011-04-23 14:16:49,661 [ |main ] DEBUG com.jolbox.bonecp.StatementHandle.executeUpdate - create table TestEntity (id bigint generated by default as identity check (id>=1), aktualisiert timestamp, angelegt timestamp, jdoDetachedState binary(255), version integer, name varchar(255) not null, primary key (id))

Is it possible to generate the field as transient or put javax.persistence.Transient as an annotation on the field when enhancing for JPA?

protected transient StateManager jdoStateManager;
protected transient byte jdoFlags;
@Transient
protected Object[] jdoDetachedState;
private static final byte[] jdoFieldFlags;
private static final Class jdoPersistenceCapableSuperclass;
private static final Class[] jdoFieldTypes;
private static final String[] jdoFieldNames = __jdoFieldNamesInit();
private static final int jdoInheritedFieldCount;

People using the GAE-Plugin for Eclipse are facing the same issue. Quote:
-- The eclipse plugin compiles hibernate objects with some crap that adds a jdoDetachedState column to all my tables. Yuck! (http://stackoverflow.com/questions/751568/gwt-upgrade-from-1-5-to-1-6)

Sort Order: Ascending order - Click to sort in descending order
Andy Jefferson added a comment - 23/Apr/11 06:01 PM
You can't make it transient since that would screw up serialisation capabilities losing detached info across serialisation boundaries.

Downgraded to minor since a DN enhanced class is for use by DN. In the same way an OpenJPA enhanced class contains things that are for OpenJPA (and DN likely wouldn't like too much). OpenJPA allows the user to define a field to provide the detached state (so then the user can mark as @Transient); to do the same with DN would require work, and obviously a low priority due to the fact that it is not our aim to provide a class that Hibernate can use; why anyone would want to use a JDO-bytecode-contract-enhanced class with Hibernate is unknown to me ... you lose all the benefits of that enhancement.

Any user making use of an Eclipse plugin ought to be aware of what the option is for, and turn on/off accordingly. Google are responsible for their plugin

subes added a comment - 24/Apr/11 02:23 AM - edited
I agree that it ain't nice to use datanucleus enhanced classes with hibernate, though there are two use-cases I have in mind:
1. using more than one persistence unit in the same application and not wanting to manually filter which classes get enhanced specifically
2. needing the flexibility to switch between jpa providers in a modular software productline by changing dependencies

Though I found a solution to the problem. I've added:

@Transient
protected Object[] jdoDetachedState;

to my base Entity class. The enhancer does not try to put it there again because of: http://www.datanucleus.org/servlet/jira/browse/NUCENHANCER-35

Using DN enhanced classes with hibernate induces some needless performance overhead to hibernate. I would rather drop the datanucleus compile time enhancement in favor of the runtime enhancement method via the javaagent, but that one broke my Entity classes all the time I tried to use it. I will open an issue for that tomorrow maybe.

--------------

To evaluate other possibilities:

Since Hibernate added the compile time enhancement as a performance optimization after they tried to stick with the proxy method for a long time, did you think about adding the proxy method to datanucleus to make it easier to integrate datanucleus and to make the development cycles for the programmers easier?

It would be nice if datanucleus supported proxy enhancement as a fallback when no other type of enhancement has been done. If users don't need the performance boost or if they need the flexibility without the configuration overhead of the javaagent, they could just let it stay enabled maybe during development and use compile time enhancement for deployment of performance critical applications. This would also reduce the adaptation hurdle of potential new users by reducing the rocket science effort of making it work initially. And it would make datanucleus better suitable for environments where ease of use is a critical factor in the evaluation of software frameworks.

What are your thoughts about this?

Andy Jefferson added a comment - 24/Apr/11 07:40 AM
Since workaround exists, no need to do this.

About proxies/reflection: DN uses proxies on (container) fields already (substituting a wrapper for the users collection/map/date). More than that, no I haven't contemplated that nor have any plans to. The issue is resourcing. DN (3.0) internals supports using other methods to changes to fields but not a priority. Obviously people could easily contribute their time to provide such features.

Bytecode enhancement is trivial to use, once people understand what they are doing.