我需要使用OpenJPA(2.2.2)在Postgres(9.0)表中记录IP地址。
我使用原生查询工作了:
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
int rows = entityManager.createNativeQuery("insert into click (ip) values (?::inet)") //
.setParameter(1, InetAddress.getLocalHost().getHostAddress()) //
.executeUpdate();
entityManager.getTransaction().commit();
entityManager.close();
但我更愿意为OpenJPA找到一种方法来处理原始查询。
我搜索并找到了其他一些建议,例如注释列:
@Column(length = -1, columnDefinition = "inet")
但这似乎不是演员。我得到了这个例外:
ERROR: column "ip" is of type inet but expression is of type character varying
Hint: You will need to rewrite or cast the expression.
Position: 32 {prepstmnt 1376458920 INSERT INTO Click (ip) VALUES (?) [params=?]} [code=0, state=42804]
我可以使用@Strategy注释字段并实现自定义FieldStrategy或ValueHandler吗?这似乎是正确的解决方案,但文档很轻,我找不到一个简单的例子来开始。
https://openjpa.apache.org/builds/2.2.2/apache-openjpa/docs/ref_guide_mapping_custom.html
修复注释或实现FieldStrategy或ValueHandler的任何方向都将受到赞赏。
编辑:我弄清楚了。由于我没有足够的代表,我无法回答我自己的问题。
我创建了一个正确执行转换的自定义DBDictionary。
package package.name.goes.here;
import org.apache.openjpa.jdbc.schema.Column;
public class PostgresDictionary extends org.apache.openjpa.jdbc.sql.PostgresDictionary {
@Override
public String getMarkerForInsertUpdate(Column col, Object val) {
String colType = col.getTypeIdentifier().getName();
if (colType != null) {
return "?::" + colType;
}
return "?";
}
}
然后只需用以下内容注释该字段:
@Column(columnDefinition = "inet")
在persistence.xml中注册自定义词典:
<property name="openjpa.jdbc.DBDictionary" value="package.name.goes.here.PostgresDictionary"/>