[ 
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.

Reply via email to