我需要使用 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"/>