Trying to store a temporal collection with Erwin Vervaet's framework and getting ClassCastException
Asked Answered
N

1

9

I'm trying to use the Bitemporal framework of Erwin Vervaet to store with Hibernate a temporal collection instead of a temporal property as in his example. (there is a presentation of the framework here)

I'm trying to store a collection of addresses which change over time, i.e. a Person can have multiple addresses at the same time, and this set of addresses can change.

The mapping works, I mean the tables are created in the db, but I get the following runtime error:

java.lang.ClassCastException: com.ervacon.bitemporal.AddressSet cannot be cast to java.util.Collection

I don't understand the error. I understand a cast is being done when Hibernate tries to build the addresses bag of Person, but why does it get a ClassCastException? If I comment out the mapping of value in the entity-name="AddressSet" mapping, I have no error, but the addresses aren't saved. So the problem is in that mapping I believe.

I also don't understand if what I'm trying to achieve can be done with this framework.

Can you help me?

How I modified Vervaet's example: I added the AddressSet class and modified the Hibernate mapping, the Person and test class

The classes involved are the following:

Person

/*
 * (c) Copyright Ervacon 2016.
 * All Rights Reserved.
 */
package com.ervacon.bitemporal;

import java.io.Serializable;
import java.util.Collection;
import java.util.LinkedList;

public class Person implements Serializable {

    private Long id;
    private String name;
    private Collection<BitemporalWrapper<AddressSet>> addresses = new LinkedList<>();
    private Collection<BitemporalWrapper<Boolean>> alive = new LinkedList<>();

    /**
     * For Hibernate.
     */
    @SuppressWarnings("unused")
    private Person() {
    }

    public Person(String name) {
        if (name == null) {
            throw new IllegalArgumentException("Name is required");
        }
        this.name = name;
    }

    public Long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public WrappedBitemporalProperty<AddressSet> addresses() {
        return new WrappedBitemporalProperty<>(addresses);
    }

    public WrappedBitemporalProperty<Boolean> alive() {
        return new WrappedBitemporalProperty<>(alive);
    }

    @Override
    public String toString() {
        return getName();
    }
}

Address

/*
 * (c) Copyright Ervacon 2016.
 * All Rights Reserved.
 */
package com.ervacon.bitemporal;

import java.io.Serializable;

public class Address implements Serializable {

    private String line1;
    private String line2;
    private String line3;

    private long id;

    /**
     * For Hibernate.
     Address.java*/
    @SuppressWarnings("unused")
    private Address() {
    }

    public Address(String line1, String line2, String line3) {
        this.line1 = line1;
        this.line2 = line2;
        this.line3 = line3;
    }

    public String getLine1() {
        return line1;
    }

    public String getLine2() {
        return line2;
    }

    public String getLine3() {
        return line3;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }
        if (obj instanceof Address) {
            Address other = (Address) obj;
            return other.line1.equals(this.line1)
                    && other.line2.equals(this.line2)
                    && other.line3.equals(this.line3);
        }
        return false;
    }

    @Override
    public int hashCode() {
        return this.line1.hashCode() + this.line2.hashCode() + this.line3.hashCode();
    }

    @Override
    public String toString() {
        return this.line1 + " " + line2 + " " + line3;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }


}

AddressSet

package com.ervacon.bitemporal;

import java.io.Serializable;
import java.util.Set;

public class AddressSet implements Serializable {

    private List<Address> addressSet;

    private long id;

    private AddressSet() {
    }

    public AddressSet(List<Address> a) {
        this.addressSet = a;
    }

    public List<Address> getAddressSet() {
        return addressSet;
    }

    public void setAddressSet(List<Address> addressSet) {
        this.addressSet = addressSet;
    }

}

The mapping is:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping default-access="field">

    <class name="com.ervacon.bitemporal.BitemporalWrapper" entity-name="AddressSet">
        <id name="id" type="long">
            <generator class="native"/>
        </id>

        <bag name="value">
            <key column="addressSet_id"/>
            <one-to-many class="com.ervacon.bitemporal.Address"/>
        </bag>

        <property name="validityInterval" type="com.ervacon.bitemporal.support.PersistentInterval">
            <column name="validityStart"/>
            <column name="validityEnd"/>
        </property>
        <property name="recordInterval" type="com.ervacon.bitemporal.support.PersistentInterval">
            <column name="recordStart"/>
            <column name="recordEnd"/>
        </property>
    </class>


    <class name="com.ervacon.bitemporal.Person">
        <id name="id" type="long">
            <generator class="native"/>
        </id>

        <property name="name"/>
        <!-- <bag name="address" cascade="all-delete-orphan">
            <key column="person_id" not-null="true" update="false"/>
            <one-to-many entity-name="Address"/>
        </bag>
         -->

        <bag name="addresses" cascade="all-delete-orphan">
            <key column="person_id" not-null="true" update="false"/>
            <one-to-many entity-name="AddressSet"/>
        </bag>

        <bag name="alive" cascade="all-delete-orphan">
            <key column="person_id" not-null="true" update="false"/>
            <one-to-many entity-name="Alive"/>
        </bag>
    </class>

    <class name="com.ervacon.bitemporal.Address">
        <id name="id" type="long">
            <generator class="native"/>
        </id>

        <property name="line1"/>
        <property name="line2"/>
        <property name="line3"/>
    </class>


    <class name="com.ervacon.bitemporal.BitemporalWrapper" entity-name="Alive">
        <id name="id" type="long">
            <generator class="native"/>
        </id>

        <property name="value" type="boolean"/>

        <property name="validityInterval" type="com.ervacon.bitemporal.support.PersistentInterval">
            <column name="validityStart"/>
            <column name="validityEnd"/>
        </property>
        <property name="recordInterval" type="com.ervacon.bitemporal.support.PersistentInterval">
            <column name="recordStart"/>
            <column name="recordEnd"/>
        </property>
    </class>
</hibernate-mapping>

The test

package com.ervacon.bitemporal;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.Before;
import org.junit.Test;

public class HibernateTest {

    private SessionFactory sessionFactory;

    @Before
    public void setUp() {
        System.err.println("Before");
        try {
            sessionFactory = new Configuration().configure().buildSessionFactory();
        } catch (HibernateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    //@After
    public void tearDown() throws Exception {
        sessionFactory.close();
        TimeUtils.clearReference();
    }

    @Test
    public void testPersistence() {
        System.err.println("Testing");
        Session session = sessionFactory.openSession();
        session.beginTransaction();

        TimeUtils.setReference(TimeUtils.day(4, 4, 1975));
        Person johnDoe = new Person("John Doe");
        johnDoe.alive().set(
                true,
                TimeUtils.from(TimeUtils.day(3, 4, 1975)));


        AddressSet addressSet = new AddressSet(new ArrayList<>());
        List<Address> addressList1 = new ArrayList<>();
        addressList1.add(new Address("Address1.1", "", ""));
        addressSet.setAddressSet(addressList1);

        johnDoe.addresses().set(
                addressSet,
                TimeUtils.from(TimeUtils.day(3, 4, 1975)));

        AddressSet addressSet2 = new AddressSet(new ArrayList<>());
        List<Address> addressList2 = new ArrayList<>();
        addressList2.add(new Address("Address2.1", "", ""));
        addressSet2.setAddressSet(addressList2);

        johnDoe.addresses().set(
                addressSet2,
                TimeUtils.from(TimeUtils.day(3, 4, 1976)));

        try {
            session.save(johnDoe);

            session.getTransaction().commit();
            session.close();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
}

The full exception is

java.lang.ClassCastException: com.ervacon.bitemporal.AddressSet cannot be cast to java.util.Collection
    at org.hibernate.type.BagType.wrap(BagType.java:35)
    at org.hibernate.event.internal.WrapVisitor.processArrayOrNewCollection(WrapVisitor.java:91)
    at org.hibernate.event.internal.WrapVisitor.processCollection(WrapVisitor.java:56)
    at org.hibernate.event.internal.AbstractVisitor.processValue(AbstractVisitor.java:104)
    at org.hibernate.event.internal.WrapVisitor.processValue(WrapVisitor.java:108)
    at org.hibernate.event.internal.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:59)
    at org.hibernate.event.internal.AbstractSaveEventListener.visitCollectionsBeforeSave(AbstractSaveEventListener.java:354)
    at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:260)
    at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:182)
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:113)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:192)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:177)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:97)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73)
    at org.hibernate.internal.SessionImpl.fireSaveOrUpdate(SessionImpl.java:651)
    at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:643)
    at org.hibernate.engine.spi.CascadingActions$5.cascade(CascadingActions.java:218)
    at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:391)
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:316)
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:155)
    at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:424)
    at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:356)
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:319)
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:155)
    at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:104)
    at org.hibernate.event.internal.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:445)
    at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:281)
    at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:182)
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:113)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:192)
    at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:38)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:177)
    at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:32)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73)
    at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:682)
    at org.hibernate.internal.SessionImpl.save(SessionImpl.java:674)
    at org.hibernate.internal.SessionImpl.save(SessionImpl.java:669)
    at com.ervacon.bitemporal.HibernateTest.testPersistence(HibernateTest.java:60)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

edit: changed Set to List in AddressSet, because after using Tijkijiki's solution I got an error while Hibernate was building the bag. After this the test passed.

But I added two set of AddressSet to the test (which is now modified since the original posting) and now I get this error, someone can explain me why? The AddressSet objects seem different to me.

ERROR: HHH000346: Error during managed flush [Found shared references to a collection: AddressSet.value.addressSet]
org.hibernate.HibernateException: Found shared references to a collection: AddressSet.value.addressSet
    at org.hibernate.engine.internal.Collections.processReachableCollection(Collections.java:182)
    at org.hibernate.event.internal.FlushVisitor.processCollection(FlushVisitor.java:42)
    at org.hibernate.event.internal.AbstractVisitor.processValue(AbstractVisitor.java:104)
    at org.hibernate.event.internal.AbstractVisitor.processValue(AbstractVisitor.java:65)
    at org.hibernate.event.internal.AbstractVisitor.processValues(AbstractVisitor.java:44)
    at org.hibernate.event.internal.AbstractVisitor.processComponent(AbstractVisitor.java:85)
    at org.hibernate.event.internal.AbstractVisitor.processValue(AbstractVisitor.java:110)
    at org.hibernate.event.internal.AbstractVisitor.processValue(AbstractVisitor.java:65)
    at org.hibernate.event.internal.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:59)
    at org.hibernate.event.internal.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:155)
    at org.hibernate.event.internal.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:216)
    at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:85)
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:38)
    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1295)
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:468)
    at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3135)
    at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2352)
    at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:491)
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:147)
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$100(JdbcResourceLocalTransactionCoordinatorImpl.java:38)
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:231)
    at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:65)
    at com.ervacon.bitemporal.HibernateTest.testPersistence(HibernateTest.java:77)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Nordgren answered 2/5, 2019 at 18:24 Comment(0)
P
3

Problem is really your mapping, BitemporalWrapper<AddressSet> should map value to AddressSet

<class name="com.ervacon.bitemporal.Person">
    <id name="id" type="long">
        <generator class="native"/>
    </id>

    <property name="name"/>
    <bag name="addresses" cascade="all-delete-orphan">
        <key column="person_id" not-null="true" update="false"/>
        <one-to-many entity-name="AddressSet"/>
    </bag>
    <bag name="alive" cascade="all-delete-orphan">
        <key column="person_id" not-null="true" update="false"/>
        <one-to-many entity-name="Alive"/>
    </bag>
</class>

<class name="com.ervacon.bitemporal.BitemporalWrapper" entity-name="AddressSet">
    <id name="id" type="long">
        <generator class="native"/>
    </id>

    <component name="value" class="com.ervacon.bitemporal.AddressSet">
        <bag name="addressSet" cascade="all-delete-orphan">
            <key column="addressSet_id" not-null="true" update="false"/>
            <one-to-many entity-name="Address"/>
        </bag>
    </component>

    <property name="validityInterval" type="com.ervacon.bitemporal.support.PersistentInterval">
        <column name="validityStart"/>
        <column name="validityEnd"/>
    </property>
    <property name="recordInterval" type="com.ervacon.bitemporal.support.PersistentInterval">
        <column name="recordStart"/>
        <column name="recordEnd"/>
    </property>
</class>

<class name="com.ervacon.bitemporal.Address" entity-name="Address">
    <id name="id" type="long">
        <generator class="native"/>
    </id>

    <property name="line1"/>
    <property name="line2"/>
    <property name="line3"/>
</class>

<class name="com.ervacon.bitemporal.BitemporalWrapper" entity-name="Alive">
    <id name="id" type="long">
        <generator class="native"/>
    </id>

    <property name="value" type="boolean"/>

    <property name="validityInterval" type="com.ervacon.bitemporal.support.PersistentInterval">
        <column name="validityStart"/>
        <column name="validityEnd"/>
    </property>
    <property name="recordInterval" type="com.ervacon.bitemporal.support.PersistentInterval">
        <column name="recordStart"/>
        <column name="recordEnd"/>
    </property>
</class>

When searching for solution I found out, that getting versioned entity is done in java, not in a query. So personally I wouldnt go this way.


Edit: From this answer

Hibernate shows this error when you attempt to persist more than one entity instance sharing the same collection reference (i.e. the collection identity in contrast with collection equality).

So I dig little bit into Bitemporal framework and I think, that problem is here, where is basicly added additional value with new record interval, but value is not copied, which is not problem in most cases. But since our object is used in two BitemporalWrappers and it has same collection reference (because its same object), exception is thrown.

To prove my theory (to be honest, this is little bit thin ice for me; Im not sure if my understanding is correct) I have made following changes in framework: Type of V implements Serializabe, so I can use commons-lang3 SerializationUtils and returning copy of V value when clonning BitemporalWrapper :

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.9</version>
</dependency>



public class BitemporalWrapper<V extends Serializable> implements Bitemporal, Serializable {

...
    @Override
    public Bitemporal copyWith(Interval validityInterval) {
        // force record interval to be 'from now'
        return new BitemporalWrapper<>(SerializationUtils.clone(value), validityInterval);
    }
...
}

public class WrappedBitemporalProperty<V extends Serializable> extends BitemporalProperty<V, BitemporalWrapper<V>> { ...  }

public class BitemporalProperty<V extends Serializable, T extends Bitemporal> implements Serializable { .. }

Now test passes. I can share my changes if you were interested.

Petrapetracca answered 15/5, 2019 at 13:47 Comment(6)
Thank you, your solution is almost ok. Can you explain why one needs a component and cannot use the bag directly as Vervaet did in the example? And, can you try to help me for the error I'm getting now? (see the edit section at the bottom of the post)Nordgren
I dont know thich example do you mean, since presentation contains their test case example. Take a look here github.com/klr8/bitemporal/blob/master/src/test/resources/com/…. Mapping of value BitemporalWrapper is to enitity as component. That was the reason of ClassCastException, since mapping to bag (collection) cannot be cast to AddressSet. Also I updated test case, changed type of addressSet to List as you mentioned, but I dont get any exception. Did you changed anything else?Petrapetracca
With "example" I meant the test case you are referring to, but I was wrong (totally missed it), also Vervaet used component, thank you for pointing it out. I didn't change anything else, but it's happening that, in the file named "The test", if I set addressSet (with johnDoe.addresses().set(...)) the test passes, but if I set addressSet2 too I get the shared references error.Nordgren
I award you with the bounty as you answered the original question, but before closing the question I'm also interested in the changes you made to the framework. Are there other changes than the ones you posted here?Nordgren
For serialization purposes I made empty constructor of AddressSet public and also added getters and setters.I'm not aware of any other changes. Do you have any other issues?Petrapetracca
Ok, now all works, thank you. It seems strange to me that the framework was broken, but it appears so.Nordgren

© 2022 - 2024 — McMap. All rights reserved.