在我的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.JSONObject
或String
那样冷静对待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/