循環参照とジェネリックスを含むprotostuffバイナリを使用しています。非常に単純なシナリオとして、次のクラスがあります。
public class A {
private String name;
private B b;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public B getB() {
return b;
}
public void setB(B b) {
this.b = b;
this.b.setA(this);
}
}
////////////////////////////////////////////////// /////////////////////////////
public class B {
private String name;
private A a;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public A getA() {
return a;
}
public void setA(A a) {
this.a = a;
}
}
////////////////////////////////////////////////// /////////////////////////////
public class Container<E> {
private E element;
private String name;
public Container() {
}
public Container(E e, String name) {
super();
this.element = e;
this.name = name;
}
public E getElement() {
return element;
}
public void setElement(E e) {
this.element = e;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
次の単体テストを実行して、ラウンドトリップのシリアル化/逆シリアル化が正しく実行されたことを確認すると、非常に奇妙な結果が得られます。最後のアサーションは失敗します:
public class CircularRefTest {
@Test
public void testCircularReferences() {
A a = new A();
a.setName("a");
B b = new B();
b.setName("b");
a.setB(b);
Container<A> container = new Container<A>(a, "container");
Schema<Container> schema = RuntimeSchema.getSchema(Container.class);
LinkedBuffer buffer = LinkedBuffer.allocate(256);
byte[] data = GraphIOUtil.toByteArray(container, schema, buffer);
Container<A> copy = new Container<A>();
GraphIOUtil.mergeFrom(data, copy, schema);
assertEquals(container.getName(), copy.getName());
assertEquals(container.getElement().getName(), copy.getElement().getName());
assertEquals(container.getElement().getB().getName(), copy.getElement().getB().getName());
// something weird happens here with the circular references here
System.out.println(copy.getElement().getB().getA().getClass());
assertTrue(copy.getElement().getB().getA() instanceof A); // fails
}
}
Protostuffは、子クラスから親に戻る循環参照を破損しています。最後のアサーションは合格するはずですが、何らかの理由でクラスはコンテナタイプです。
私は何が間違っているのですか?
強く型付けされたオブジェクトを使用するようにContainerクラスを変更すると、単体テストに合格します。これはバグですか?
私が使用しているMavenアーティファクトは次のとおりです。
<dependency>
<groupId>com.dyuproject.protostuff</groupId>
<artifactId>protostuff-api</artifactId>
<version>1.0.4</version>
</dependency>