openjpa-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Fay Wang <fyw...@yahoo.com>
Subject Re: Help on basic @Strategy
Date Tue, 09 Mar 2010 17:31:00 GMT
Hi Jerry,
   Ok, I take out the OneToOne annotation, and employ inheritance as shown below. The test
works just fine. I don't see unmanaged object exception. 

(1)
@Entity
public class SimpleEntity {
    @Id
    private long id;
    public long getId() { return id; }
    public void setId(long id) { this.id = id; }
   
    @Strategy("MyPointHandler")
    @Persistent(fetch = FetchType.LAZY)
    private MyPoint custom;
    public MyPoint getCustom() { return custom; }
    public void setCustom(MyPoint custom) { this. custom = custom; }
}

(2)
public class MyPoint {
    String val;
    public MyPoint(String val) { this.val = val; }
    public String getValue() { return val; }
}

(3)
public class SpecializedPoint extends MyPoint {
    int intVal;
    public SpecializedPoint(String val) { super(val); }
 
    public SpecializedPoint(String val, int intVal) {
        super(val);
        this.intVal = intVal;
    }

    public int getIntVal() { return intVal; }
    public void setIntVal(int intVal) { this.intVal = intVal; }
}

(4)
public class MyPointHandler extends AbstractValueHandler {
    public Column[] map(ValueMapping vm, DBIdentifier name, ColumnIO io,
        boolean adapt) {
        String dbIdName = name.getName();
        Column c1 = new Column();
        c1.setIdentifier(DBIdentifier.newColumn(dbIdName + "_val"));
        c1.setJavaType(JavaTypes.STRING);
        
        Column c2 = new Column();
        c2.setIdentifier(DBIdentifier.newColumn(dbIdName + "_intVal"));
        c2.setJavaType(JavaTypes.INT_OBJ);

        return new Column[]{ c1, c2 };
    }    
    
    public Column[] map(ValueMapping vm, String name, ColumnIO io, boolean adapt)  {
        Column c1 = new Column();
        c1.setIdentifier(DBIdentifier.newColumn(name + "_val"));
        c1.setJavaType(JavaTypes.STRING);

        Column c2 = new Column();
        c2.setIdentifier(DBIdentifier.newColumn(name + "_intVal"));
        c2.setJavaType(JavaTypes.INT_OBJ);

        return new Column[]{ c1, c2 };
    }
    
    public boolean isVersionable() {
        return true;
    }
    
    public Object toDataStoreValue(ValueMapping vm, Object val, JDBCStore store) {
        return new Object[] {((SpecializedPoint)val).getValue(), 
                ((SpecializedPoint)val).getIntVal()};
    }
   
    public Object toObjectValue(ValueMapping vm, Object val) {
        Object[] objVal = (Object[]) val;
        return new SpecializedPoint((String)objVal[0], (Integer)objVal[1]);
    }
 }

(5) Here is my test program:
    public void testStrat() {
        EntityManager em = emf.createEntityManager();
        
        SimpleEntity e = new SimpleEntity();
        e.setId(1);
        SpecializedPoint custom = new SpecializedPoint("myPoint", 1);
        e.setCustom(custom);
        em.persist(e);
        em.getTransaction().begin();
        em.getTransaction().commit();
        em.clear();
        
        SimpleEntity e1 = em.find(SimpleEntity.class, 1);
        System.out.println("e1 = " + e1);
    }

Fay






----- Original Message ----
From: No1UNo <jerry@jerrycarter.org>
To: users@openjpa.apache.org
Sent: Mon, March 8, 2010 8:08:55 PM
Subject: Re: Help on basic @Strategy



On Mar 8, 2010, at 4:03 PM, No1UNo [via OpenJPA] wrote:

> The 'unmanaged object' exception is being caused by an inheritance relationship on the
Java side.  Suppose that I have a specialized class derive from a base class: 'class SpecializedPoint
extends MyPoint'.  If I write the entity as
> 
>> 
>> @Strategy("MyPointHandler") 
>> private SpecializedPoint custom; 
>> SpecializedPoint getCustom() { return custom; } 
>> void setCustom(SpecializedPoint custom) { this. custom = custom; } 
> 
> everything works fine.  If instead I have
> 
>> 
>> @Strategy("MyPointHandler") 
>> private MyPoint custom; 
>> MyPoint getCustom() { return custom; } 
>> void setCustom(MyPoint custom) { this. custom = custom; } 
> 
> and call 'setCustom(new SpecializedPoint())' then the exception is thrown when the data
should be written to the database and BEFORE ever calling the class designated by @Strategy.
> 
> Is this a bug in OpenJPA 2.0.0?  Most likely the behavior is by design.  This prevents
scenarios where the child class requires persisting more information than the base class.
 Unfortunately, it doesn't help much in my case as the objects are serializing binary data
to the database and only a single column is required for the whole family of classes.  Is
there a different mechanism for this scenario?

FWIW, I've employed a slightly different workaround.  I defined a simple class holding the
base class and made corresponding changes to the setter, getter, and strategy class.

> @Strategy("MyPointHandler")
> private HolderClass custom;
> MyPoint GetCustom() { return custom.getPoint(); }
> void setCustom(MyPoint custom) { custom = new HolderClass(custom); }

This seems unnecessary but it works.


-- 
View this message in context: http://n2.nabble.com/Help-on-basic-Strategy-tp4696891p4700217.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.



      

Mime
View raw message