Java Microstream – 合成类 – PersistenceExceptionTypeNotPersistable

huangapple go评论128阅读模式
英文:

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

  1. 实现一个名为CustomBinaryHandler的处理器,用于处理具有合成类/静态引用的对象。
  2. 重写store方法。
  3. 重写create方法。
  4. 重写initializeState方法。

存储

如果引用是合成类/静态引用之一,请创建对象的新实例,并将引用设置为“标记”。在我的情况下,设置为null。不要更新传递给store方法的当前对象,确保创建克隆并修改适用的引用。然后调用super.store()

创建

创建对象的空实例。

初始化状态

  1. 检索对象的值。
  2. 如果涉及的值有“标记”,则将其设置为合成类/静态引用。
  3. 创建克隆对象并用值填充。
  4. 从克隆中使用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.

  1. Implement a CustomBinaryHandler for the Object that has the Synthetic Classes/static reference
  2. Override the store method
  3. Override the create method
  4. 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

  1. Retrieve the values for the Object
  2. If the value in question has the 'marker' then set it to the Synthetic Classes/static reference
  3. Create a clone object and populate with the values
  4. XReflect.copyFields from the clone to the real instance
public class ExampleTypeHandler extends CustomBinaryHandler&lt;Example&gt; {
private static Class&lt;Example&gt; handledType() {
return Example.class; // to get &quot;.class&quot; to work
}
//the fields to be persisted
BinaryField&lt;Example&gt; accompanying = Field(Object.class, Example::getAccompanying);
BinaryField&lt;Example&gt; resulting = Field(Object.class, Example::getResulting);
public ExampleTypeHandler()
{
super(handledType());
}
@Override
public void store(Binary data, Example dtl, long objectId, PersistenceStoreHandler&lt;Binary&gt; 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);
}		
}

huangapple
  • 本文由 发表于 2020年8月5日 21:41:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/63266488.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定