在我的PostgreSQL数据库中,我有:

CREATE TABLE category (
    // ...
    category_name_localization JSON not null,
);

在Java中,我有一个JDO类,如下所示:
@javax.jdo.annotations.PersistenceCapable(table = "category" )
public class Category extends _BlueEntity implements Serializable {
    //...

    private org.json.simple.JSONObject category_name_localization;

    @javax.jdo.annotations.Column( name = "category_name_localization" )
    public org.json.simple.JSONObject getCategoryNameLocalization() {
        return category_name_localization;
    }
}

当我使用这个类时,DataNucleus会给出以下异常:
org.datanucleus.exceptions.NucleusUserException: Field "com.advantagegroup.blue.ui.entity.Category.category_name_localization" is a map that has been specified without a join table and neither the key nor the value has a mapped-by specified. This is invalid!
                at org.datanucleus.store.rdbms.RDBMSStoreManager.newJoinTable(RDBMSStoreManager.java:2720)
                at org.datanucleus.store.rdbms.mapping.java.AbstractContainerMapping.initialize(AbstractContainerMapping.java:82)
                at org.datanucleus.store.rdbms.mapping.MappingManagerImpl.getMapping(MappingManagerImpl.java:680)
                at org.datanucleus.store.rdbms.table.ClassTable.manageMembers(ClassTable.java:518)
                at org.datanucleus.store.rdbms.table.ClassTable.manageClass(ClassTable.java:424)
                at org.datanucleus.store.rdbms.table.ClassTable.initializeForClass(ClassTable.java:1250)
                at org.datanucleus.store.rdbms.table.ClassTable.initialize(ClassTable.java:271)
                at org.datanucleus.store.rdbms.RDBMSStoreManager$ClassAdder.initializeClassTables(RDBMSStoreManager.java:3288)
                at org.datanucleus.store.rdbms.RDBMSStoreManager$ClassAdder.run(RDBMSStoreManager.java:2897)
                at org.datanucleus.store.rdbms.AbstractSchemaTransaction.execute(AbstractSchemaTransaction.java:118)
                at org.datanucleus.store.rdbms.RDBMSStoreManager.manageClasses(RDBMSStoreManager.java:1637)
                at org.datanucleus.store.rdbms.RDBMSStoreManager.getDatastoreClass(RDBMSStoreManager.java:665)
                at org.datanucleus.store.rdbms.RDBMSStoreManager.getPropertiesForGenerator(RDBMSStoreManager.java:2098)
                at org.datanucleus.store.AbstractStoreManager.getStrategyValue(AbstractStoreManager.java:1278)
                at org.datanucleus.ExecutionContextImpl.newObjectId(ExecutionContextImpl.java:3668)
                at org.datanucleus.state.StateManagerImpl.setIdentity(StateManagerImpl.java:2276)
                at org.datanucleus.state.StateManagerImpl.initialiseForPersistentNew(StateManagerImpl.java:482)
                at org.datanucleus.state.StateManagerImpl.initialiseForPersistentNew(StateManagerImpl.java:122)
                at org.datanucleus.state.ObjectProviderFactoryImpl.newForPersistentNew(ObjectProviderFactoryImpl.java:218)
                at org.datanucleus.ExecutionContextImpl.persistObjectInternal(ExecutionContextImpl.java:1986)
                at org.datanucleus.ExecutionContextImpl.persistObjectWork(ExecutionContextImpl.java:1830)
                at org.datanucleus.ExecutionContextImpl.persistObject(ExecutionContextImpl.java:1685)
                at org.datanucleus.api.jdo.JDOPersistenceManager.jdoMakePersistent(JDOPersistenceManager.java:712)
                at org.datanucleus.api.jdo.JDOPersistenceManager.makePersistent(JDOPersistenceManager.java:738)
                at com.advantagegroup.blue.ui.jdo._BlueJdo.insert(_BlueJdo.java:40)
                at ...

这个错误在某种程度上是有意义的,因为org.json.simple.JSONObject扩展了Map。然而,这个字段不是任何关系的一部分——它是JSON类型的,因此用JSONObject支持它是很自然的
我该如何告诉JDO/DataNucleus像对待org.json.simple.JSONObjectString那样冷静对待Date
谢谢!
直流

最佳答案

我的理解是,您的默认尝试是试图保持一个正常的Map(因为虽然它不知道JSONObject是什么,但它确实知道Map是什么),并且它需要一个用于RDBMS的连接表。
因为您可能希望将JSONObject持久化为一个列,所以需要创建一个JDOAttributeConverter。我用自己的类型做过类似的事情,而且工作得很好(我使用的是v5.0.5iirc)。
我还发现了this in their docs,因为当您有自己的Map类时,它在默认情况下不知道如何用代理替换它(拦截put、putAll等调用)。如果添加该行,它将不会尝试用代理包装该字段(除非您告诉它,否则它不知道如何处理该类型的代理)。如果您想自动检测JSONObject变“脏”,那么您需要根据this page编写一个代理包装器。
这并不能回答如何将该转换器的列映射为在PostgreSQL中使用“json”类型,但我猜如果设置sqlType,您可能会在这方面获得成功。

关于json - JDO,org.json.simple.JSONObject和PostgreSQL JSON类型,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42724747/

10-15 20:35