英文:
Java Microstream - Synthetic classes - PersistenceExceptionTypeNotPersistable
问题
使用Microstream时出现以下异常。
由于类引用了静态内部类而引起。
如何解决这个问题?
异常说明如下,但文档未说明如何实现PersistenceTypeResolver
详细信息:合成类($1等)不可靠地持久化,因为源代码元素的简单重新排序会更改类的名称标识。对于必须依靠按其标识名称解析类型的类型系统,这将悄悄地导致潜在的致命错误。如果绝对需要处理合成类(例如匿名内部类),可以使用自定义的one.microstream.persistence.types.PersistenceTypeResolver来删除异常,并承担正确处理合成类名称的完全责任。
在one.microstream.persistence.types.Persistence.java:1083处
public static final AbstractAccompanyingPassenger DUMMY = new AbstractAccompanyingPassenger(MetaDataAccompanyingType.DUMMY) {
@Override
public AbstractAccompanyingPassenger clone() {
return DUMMY;
}};
由于:one.microstream.persistence.exceptions.PersistenceExceptionTypeNotPersistable: 类型不可持久化:“class net.atpco.metadata.summary.accompanied.MetaDataAccompanying$1”。详细信息:合成类($1等)不可靠地持久化,因为源代码元素的简单重新排序会更改类的名称标识。对于必须依靠按其标识名称解析类型的类型系统,这将悄悄地导致潜在的致命错误。如果绝对需要处理合成类(例如匿名内部类),可以使用自定义的one.microstream.persistence.types.PersistenceTypeResolver来删除异常,并承担正确处理合成类名称的完全责任。
在one.microstream.persistence.types.Persistence.java:1083处
在one.microstream.persistence.types.PersistenceTypeResolver.java:17处
在one.microstream.persistence.types.PersistenceTypeHandlerCreator.java:73处
在one.microstream.persistence.binary.types.BinaryTypeHandlerCreator.java:238处
在one.microstream.persistence.types.PersistenceTypeHandlerCreator.java:168处
在one.microstream.persistence.types.PersistenceTypeHandlerEnsurer.java:199处
在one.microstream.persistence.internal.PersistenceTypeHandlerProviderCreating.java:170处
在one.microstream.persistence.internal.PersistenceTypeHandlerProviderCreating.java:78处
在one.microstream.persistence.types.PersistenceTypeHandlerManager.java:587处
在one.microstream.persistence.types.PersistenceTypeHandlerManager.java:357处
在one.microstream.persistence.types.PersistenceTypeHandlerManager.java:333处
在one.microstream.persistence.binary.types.BinaryStorer.java:557处
在one.microstream.persistence.binary.types.BinaryStorer.java:572处
在one.microstream.persistence.types.PersistenceObjectManager.java:182处
在one.microstream.persistence.binary.types.BinaryStorer.java:591处
在one.microstream.persistence.binary.types.BinaryStorer.java:298处
在one.microstream.persistence.binary.types.BinaryValueFunctions.java:147处
在one.microstream.persistence.binary.types.Binary.java:1149处
在one.microstream.persistence.binary.internal.AbstractBinaryHandlerReflective.java:497处
在one.microstream.persistence.binary.internal.AbstractBinaryHandlerReflective.java:1处
在one.microstream.persistence.binary.types.BinaryStorer.java:414处
在one.microstream.persistence.binary.types.BinaryStorer.java:403处
在one.microstream.persistence.binary.types.BinaryStorer.java:421处
在one.microstream.persistence.types.PersistenceManager.java:274处
在one.microstream.storage.types.StorageConnection.java:306处
在one.microstream.cache.CacheStore.java:112处
英文:
Using Microstream getting the below exception.
Being caused by a class with a reference to a static inner class.
How do I resolve this issue?
The exception states the following, but the documentation doesn't explain how to implement a PersistenceTypeResolver
> Details: Synthetic classes ($1 etc.) are not reliably persistence since a simple reordering of source code elements would change the name identity of a class. For a type system that has to rely upon resolving types by their identifying name, this would silently cause a potentially fatal error. If handling synthetic classes (e.g. anonymous inner classes) is absolutely necessary, a custom one.microstream.persistence.types.PersistenceTypeResolver can be used to remove the exception and assume complete responsibility for correctly handling synthetic class names.
at one.microstream.persistence.types.Persistence.derivePersistentTypeName(Persistence.java:1083)
public static final AbstractAccompanyingPassenger DUMMY = new AbstractAccompanyingPassenger(MetaDataAccompanyingType.DUMMY) {
@Override
public AbstractAccompanyingPassenger clone() {
return DUMMY;
}};
Caused by: one.microstream.persistence.exceptions.PersistenceExceptionTypeNotPersistable: Type not persistable: "class net.atpco.metadata.summary.accompanied.MetaDataAccompanying$1". Details: Synthetic classes ($1 etc.) are not reliably persistence since a simple reordering of source code elements would change the name identity of a class. For a type system that has to rely upon resolving types by their identifying name, this would silently cause a potentially fatal error. If handling synthetic classes (e.g. anonymous inner classes) is absolutely necessary, a custom one.microstream.persistence.types.PersistenceTypeResolver can be used to remove the exception and assume complete responsibility for correctly handling synthetic class names.
at one.microstream.persistence.types.Persistence.derivePersistentTypeName(Persistence.java:1083)
at one.microstream.persistence.types.PersistenceTypeResolver.deriveTypeName(PersistenceTypeResolver.java:17)
at one.microstream.persistence.types.PersistenceTypeHandlerCreator$Abstract.deriveTypeName(PersistenceTypeHandlerCreator.java:73)
at one.microstream.persistence.binary.types.BinaryTypeHandlerCreator$Default.internalCreateTypeHandlerGeneric(BinaryTypeHandlerCreator.java:238)
at one.microstream.persistence.types.PersistenceTypeHandlerCreator$Abstract.createTypeHandlerGeneric(PersistenceTypeHandlerCreator.java:168)
at one.microstream.persistence.types.PersistenceTypeHandlerEnsurer$Default.ensureTypeHandler(PersistenceTypeHandlerEnsurer.java:199)
at one.microstream.persistence.internal.PersistenceTypeHandlerProviderCreating.ensureTypeHandler(PersistenceTypeHandlerProviderCreating.java:170)
at one.microstream.persistence.internal.PersistenceTypeHandlerProviderCreating.provideTypeHandler(PersistenceTypeHandlerProviderCreating.java:78)
at one.microstream.persistence.types.PersistenceTypeHandlerManager$Default.internalEnsureTypeHandler(PersistenceTypeHandlerManager.java:587)
at one.microstream.persistence.types.PersistenceTypeHandlerManager$Default.ensureTypeHandler(PersistenceTypeHandlerManager.java:357)
at one.microstream.persistence.types.PersistenceTypeHandlerManager$Default.ensureTypeHandler(PersistenceTypeHandlerManager.java:333)
at one.microstream.persistence.binary.types.BinaryStorer$Default.registerGuaranteed(BinaryStorer.java:557)
at one.microstream.persistence.binary.types.BinaryStorer$Default.registerLazyOptional(BinaryStorer.java:572)
at one.microstream.persistence.types.PersistenceObjectManager$Default.ensureObjectId(PersistenceObjectManager.java:182)
at one.microstream.persistence.binary.types.BinaryStorer$Default.register(BinaryStorer.java:591)
at one.microstream.persistence.binary.types.BinaryStorer$Default.apply(BinaryStorer.java:298)
at one.microstream.persistence.binary.types.BinaryValueFunctions$9.storeValueFromMemory(BinaryValueFunctions.java:147)
at one.microstream.persistence.binary.types.Binary.storeFixedSize(Binary.java:1149)
at one.microstream.persistence.binary.internal.AbstractBinaryHandlerReflective.store(AbstractBinaryHandlerReflective.java:497)
at one.microstream.persistence.binary.internal.AbstractBinaryHandlerReflective.store(AbstractBinaryHandlerReflective.java:1)
at one.microstream.persistence.binary.types.BinaryStorer$Default.storeItem(BinaryStorer.java:414)
at one.microstream.persistence.binary.types.BinaryStorer$Default.storeGraph(BinaryStorer.java:403)
at one.microstream.persistence.binary.types.BinaryStorer$Default.store(BinaryStorer.java:421)
at one.microstream.persistence.types.PersistenceManager$Default.store(PersistenceManager.java:274)
at one.microstream.storage.types.StorageConnection.store(StorageConnection.java:306)
at one.microstream.cache.CacheStore$Default.write(CacheStore.java:112)
答案1
得分: 1
异常说明,持久化合成类不受支持。
在您的情况下,重构您的类以摆脱这些合成类是唯一可靠的选项。
英文:
As the exception states persisting synthetic classes is not supported.
In your case refactoring your classes to get rid of those synthetic classes is the only reliable option.
答案2
得分: 0
- 实现一个名为CustomBinaryHandler的处理器,用于处理具有合成类/静态引用的对象。
- 重写store方法。
- 重写create方法。
- 重写initializeState方法。
存储
如果引用是合成类/静态引用之一,请创建对象的新实例,并将引用设置为“标记”。在我的情况下,设置为null。不要更新传递给store方法的当前对象,确保创建克隆并修改适用的引用。然后调用super.store()
创建
创建对象的空实例。
初始化状态
- 检索对象的值。
- 如果涉及的值有“标记”,则将其设置为合成类/静态引用。
- 创建克隆对象并用值填充。
- 从克隆中使用XReflect.copyFields复制到实际实例。
public class ExampleTypeHandler extends CustomBinaryHandler<Example> {
private static Class<Example> handledType() {
return Example.class; // 使“.class”正常工作
}
// 要持久化的字段
BinaryField<Example> accompanying = Field(Object.class, Example::getAccompanying);
BinaryField<Example> resulting = Field(Object.class, Example::getResulting);
public ExampleTypeHandler()
{
super(handledType());
}
@Override
public void store(Binary data, Example dtl, long objectId, PersistenceStoreHandler<Binary> handler) {
if (dtl.getAccompanying() == MetaDataAccompanying.DUMMY) {
dtl = Example.of(dtl.getResulting(), null);
}
super.store(data, dtl, objectId, handler);
}
@Override
public Example create(final Binary data, final PersistenceLoadHandler handler) {
return Example.of(null, null);
}
@Override
public void initializeState(final Binary data, final Example instance, final PersistenceLoadHandler handler) {
// 获取引用的对象
Object accompanying = this.accompanying.readReference(data, handler);
String r = (String)this.resulting.readReference(data, handler);
if (accompanying == null) {
accompanying = MetaDataAccompanying.DUMMY;
}
MetaDataAccompanying a = (MetaDataAccompanying) accompanying;
Example dtl = Example.of(r, a);
XReflect.copyFields(dtl, instance);
}
}
英文:
I have found a solution to this problem without the need to change the Java Object graph structure and have Synthetic Classes/static references.
- Implement a CustomBinaryHandler for the Object that has the Synthetic Classes/static reference
- Override the store method
- Override the create method
- Override the initializeState method
Store
If the reference is to a Synthetic Classes/static references create a new instance of the Object and set the reference to a 'marker'. In my case to a null. Do not update the current object passed into the store method, ensure create a clone and modify the applicable reference. Then call super.store()
create
Create an empty instance of the Object
initializeState
- Retrieve the values for the Object
- If the value in question has the 'marker' then set it to the Synthetic Classes/static reference
- Create a clone object and populate with the values
- XReflect.copyFields from the clone to the real instance
public class ExampleTypeHandler extends CustomBinaryHandler<Example> {
private static Class<Example> handledType() {
return Example.class; // to get ".class" to work
}
//the fields to be persisted
BinaryField<Example> accompanying = Field(Object.class, Example::getAccompanying);
BinaryField<Example> resulting = Field(Object.class, Example::getResulting);
public ExampleTypeHandler()
{
super(handledType());
}
@Override
public void store(Binary data, Example dtl, long objectId, PersistenceStoreHandler<Binary> handler) {
if (dtl.getAccompanying() == MetaDataAccompanying.DUMMY) {
dtl = Example.of(dtl.getResulting(), null);
}
super.store(data, dtl, objectId, handler);
}
@Override
public Example create(final Binary data, final PersistenceLoadHandler handler) {
return Example.of(null, null);
}
@Override
public void initializeState(final Binary data, final Example instance, final PersistenceLoadHandler handler) {
//get the referenced Objects
Object accompanying = this.accompanying.readReference(data, handler);
String r = (String)this.resulting.readReference(data, handler);
if (accompanying == null) {
accompanying = MetaDataAccompanying.DUMMY;
}
MetaDataAccompanying a = (MetaDataAccompanying) accompanying;
Example dtl = Example.of(r, a);
XReflect.copyFields(dtl, instance);
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论