You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@openjpa.apache.org by "Milosz Tylenda (JIRA)" <ji...@apache.org> on 2010/06/25 09:17:49 UTC
[jira] Commented: (OPENJPA-1687) @Strategy and @ElementStrategy
handling resets/obstructs SQL type set in the custom handler map() call.
[ https://issues.apache.org/jira/browse/OPENJPA-1687?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12882475#action_12882475 ]
Milosz Tylenda commented on OPENJPA-1687:
-----------------------------------------
Krzysztof has confirmed in private mail that the following mapping gives what is desired - schema tool creates a column of type float8[] and persisting and reading primitive arrays works correctly.
1. Modify the Handler like this:
public class PostgresJPAArrayHandler
extends AbstractValueHandler {
public PostgresJPAArrayHandler()
{
}
/**
* Serialization ID
*/
private static final long serialVersionUID = 1L;
private static final PostgresJPAArrayHandler _instance =
new PostgresJPAArrayHandler();
/**
* Singleton instance.
*/
public static PostgresJPAArrayHandler getInstance() {
return _instance;
}
public Column[] map(ValueMapping vm, String name, ColumnIO io,
boolean adapt) {
Column col = new Column();
col.setName(name);
col.setTypeName("float8[]");
col.setJavaType(JavaSQLTypes.SQL_ARRAY);
return new Column[]{ col };
}
public Object toDataStoreValue(ValueMapping vm, Object val,
JDBCStore store) {
//this has to be array of some integer or double for now
if (val instanceof double[]) {
try {
Connection unwrapped = ((DelegatingConnection) store.getConnection()).getInnermostDelegate();
Array darr = unwrapped.createArrayOf("float8", (Object[]) ( ArrayUtils.toObject((double[])val)));
return darr;
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}
/** Convert from DB rep into OM representation */
public Object toObjectValue(ValueMapping vm, Object val) {
if (val == null)
return null;
try {
return ArrayUtils.toPrimitive((Double[])((Array)val).getArray());
} catch (SQLException e) {
// TODO Auto-generated catch block
return null;
}
}
}
2. Annotate the field:
@PersistentCollection
@Strategy("milosz.pgsql.handler.PostgresJPAArrayHandler")
private double[] tabka;
3. Provide an extended PostgresDictionary with this overridden method:
public void setBlobObject(PreparedStatement stmnt, int idx, Object val,
Column col, JDBCStore store)
throws SQLException {
if (col.getTypeName().equals("float8[]")) {
setArray(stmnt, idx, (Array) val, col);
return;
}
setBytes(stmnt, idx, serialize(val, store), col);
}
> @Strategy and @ElementStrategy handling resets/obstructs SQL type set in the custom handler map() call.
> -------------------------------------------------------------------------------------------------------
>
> Key: OPENJPA-1687
> URL: https://issues.apache.org/jira/browse/OPENJPA-1687
> Project: OpenJPA
> Issue Type: Bug
> Affects Versions: 2.0.0
> Environment: OS X, Linux
> Reporter: Krzysztof
> Assignee: Milosz Tylenda
>
> OpenJPA advertises itself as an expandable framework and provides @Strategy (and undocumented) @ElementStrategy annotations to create custom java<->SQL mappings.
> I would like to create support for already existing JDBC4 standard mapping of primitive arrays in i.e. Postgres:
> java double[] <-> SQL float8[]
> Unfortunately it is not possible using @Strategy as enhancer blindly checks if the field is a collection/array and refuses to do anything with it.
> In the case like this a field should not be delegated to an external table but simply embedded - same way LOBs are, with different toDataStoreValue/toObjectValue pair as provided in the strategy implementation below..
> If we use @ElementStrategy however, i.e.:
> <class>
> @PersistentCollection
> @ElementStrategy("gaia.cu7.dal.PostgresJPAArrayHandler")
> @ElementColumns({
> @ElementColumn(name="TDOUBLE")
> })
> private double tdouble[];
> </class>
> then enhancer accepts it. Schema synchronisation creates wrong DDL suppressing given SQL type and mapping it to SQL keyword ARRAY in the external table.
> Does this rather simple requirement is not covered by openJPA?
> public class PostgresJPAArrayHandler
> extends AbstractValueHandler {
> public PostgresJPAArrayHandler()
> {
>
> }
> /**
> * Serialization ID
> */
> private static final long serialVersionUID = 1L;
> private static final PostgresJPAArrayHandler _instance =
> new PostgresJPAArrayHandler();
> /**
> * Singleton instance.
> */
> public static PostgresJPAArrayHandler getInstance() {
> return _instance;
> }
> public Column[] map(ValueMapping vm, String name, ColumnIO io,
> boolean adapt) {
> Column col = new Column();
> col.setName(name);
> col.setType(JavaSQLTypes.SQL_ARRAY);
> col.setTypeName("float8[]"); //////<<<--------------------- this gets reset in mergeField or whereabouts
>
> return new Column[]{ col };
> }
> public Object toDataStoreValue(ValueMapping vm, Object val,
> JDBCStore store) {
> //this has to be array of some integer or double for now
> if (val instanceof double[]) {
>
> try {
> Array darr = store.getConnection().createArrayOf("double", (Object[]) ( ArrayUtils.toObject((double[])val)));
> return darr;
> } catch (SQLException e) {
> // TODO Auto-generated catch block
> e.printStackTrace();
> }
>
> }
> return null;
> }
> /** Convert from DB rep into OM representation */
> public Object toObjectValue(ValueMapping vm, Object val) {
> if (val == null)
> return null;
> return ArrayUtils.toPrimitive((Double[])val);
> }
>
> }
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.