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.