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 <[email protected]>
To: [email protected]
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.



      

Reply via email to