2

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

0 回答 0