使用EclipseLink JPA将XML类型存储到PostgreSQL

时间:2013-06-26 01:37:44

标签: java postgresql jpa eclipselink

我是JPA的新手,我有一个关于如何使用JPA将XML类型存储到PostgreSQL的问题。我只是扩展现有的POJO以包括将其他XML字段持久保存到列中。 POJO看起来像这样(我故意省略了一些其他的列来缩短它,在添加这个额外的XML类型之前,这个POJO可以通过JPA很好地持久化到PostgreSQL中。)

public class Finding implements Serializable {

private static final long serialVersionUID = -5814053129578212916L;
    ...
    @Column(name = "PLUGIN_TEXT_XML")
    private String pluginTextXML;

    public void setPluginText(String pluginText) {
        this.pluginText = pluginText;
    }
    public String getPluginTextXML() {
            return pluginTextXML;
    }
}

当我尝试坚持这个POJO时,我收到了PSQLException

Caused by: org.postgresql.util.PSQLException: ERROR: column "plugin_text_xml" is of type xml but expression is of type character varying
  Hint: You will need to rewrite or cast the expression.
  Position: 668

我一直在尝试在线查看如何在JPA中映射XML类型,但没有运气。如果有人可以帮助我或指向我在线网站,那么我可以阅读更多信息,那将是一个很大的帮助!谢谢你的阅读!

2 个答案:

答案 0 :(得分:4)

对于像jsonxml等文本类型之间的隐式转换,PostgreSQL非常严格。

严格正确的解决方案是在使用JDBC设置参数时使用setObject(the_string, java.sql.Types.SQLXML)。这很难通过ORM层,并且许多ORM似乎不直接理解SQL / XML类型。

你可以告诉PostgreSQL允许通过修改系统目录隐式地进行从textxml的转换。它并不理想,但它会起作用。

psql中,您可以使用\dC xml将猫列入xml

                               List of casts
    Source type    |    Target type    |      Function      |   Implicit?   
-------------------+-------------------+--------------------+---------------
 character         | xml               | xml                | no
 character varying | xml               | xml                | no
 text              | xml               | xml                | no
 xml               | character         | (binary coercible) | in assignment
 xml               | character varying | (binary coercible) | in assignment
 xml               | text              | (binary coercible) | in assignment
(6 rows)

请参阅“隐含:否”?

你需要让它们分配 - 可转换。由于它们是内置类型,因此不能CREATE CAST,因此您必须直接更新目录,更改pg_cast表。

UPDATE pg_cast SET castcontext = 'a' 
FROM pg_cast c 
INNER JOIN pg_type srctype ON (c.castsource = srctype.oid)
INNER JOIN pg_type dsttype on (c.casttarget = dsttype.oid) 
WHERE pg_cast.oid = c.oid 
  AND srctype.typname IN ('text','varchar') 
  AND dsttype.typname = 'xml';

使用系统目录进行混乱可能会产生意外影响。在这种情况下,我认为做出这种改变是相当安全的,但它仍然在弄乱系统的内部。自行承担风险。

答案 1 :(得分:1)

您可以使用Converter在String和Postgres XML类型之间进行转换。

否则,您可以扩展PostgreSQLPlatform以支持该类型。 (请参阅DatabasePlatform.setParameterValueInDatabaseCall(),DatabasePlatform.getCustomModifyValueForCall()和DatabasePlatform.shouldUseCustomModifyForCall())。

如果你不能让它工作,我建议你也记录一个bug。应该有一个简单的方法来做到这一点。