私が使用しようとしているBitemporal枠組み彼の例のように一時的な性質の代わりに休止状態でストアに一時的なコレクションをアーウィンVervaetのを。(フレームワークの発表があり、ここで)
私は時間をかけて、すなわちAの人が同時に複数のアドレスを持つことができます変更アドレスの収集を保存しようとしている、とアドレスのこのセットは変更することができます。
マッピングの作品は、私は意味のテーブルがDBに作成されますが、私は、次のランタイムエラーを取得します:
java.lang.ClassCastException: com.ervacon.bitemporal.AddressSet cannot be cast to java.util.Collection
私は、エラーを理解していません。私は、Hibernateが構築しようとしたときにキャストが行われている理解addresses
の袋Person
が、なぜそれが得るんClassCastException
?私はのマッピングをコメントアウトした場合value
にentity-name="AddressSet"
マッピング、私はエラーを持っていませんが、アドレスが保存されません。だから、問題は、私は信じているマッピングです。
私が達成しようとしているこのフレームワークで行うことができる場合、私にも理解していません。
手伝って頂けますか?
どのように私はVervaetの変形例:私はAddressSetクラスを追加し、Hibernateのマッピング、人とテストクラスを修正しました
関連するクラスは、次のとおりです。
人
/*
* (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();
}
}
住所
/*
* (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;
}
}
マッピングは次のとおりです。
<?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>
テスト
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();
}
}
完全な例外はあります
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)
編集:変更Set
するList
にはAddressSet
、Hibernateが袋を構築している間にTijkijikiのソリューションを使用した後、私はエラーを得たので、。この後、試験を合格しました。
私は2組の追加しかし、AddressSet
(今元の投稿以降に変更された)テストのを、今、私はこのエラーを取得し、誰かが私に理由を説明することができますか?AddressSetオブジェクトは、私には違うようです。
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)
問題は、本当にあなたのマッピングで、 BitemporalWrapper<AddressSet>
マッピングする必要がありますvalue
に 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>
ソリューションを検索する場合、私はなっバージョン管理エンティティはJavaで、行われていること、を発見ないクエリで。だから、個人的に私はこの道を行くwouldntは。
編集:からこの答え
あなたが同じコレクションの参照(コレクションの平等とは対照的に、すなわち収集アイデンティティ)を共有するより1つのエンティティのインスタンスよりも持続しようとするとHibernateはこのエラーを示します。
私はBitemporalフレームワークに少し掘ると私は思うので、その問題があり、ここで basicly新記録間隔で付加価値を追加されますが、どこ、値がコピーされていないほとんどの場合、問題ではありませんこれは、。私たちのオブジェクトが2 BitemporalWrappersに使用され、それが(その同じオブジェクトので)同じコレクションの参照を持っているのでしかし、例外がスローされます。
種類:;私の理論を証明するために(正直に言うと、これは私のために少し薄い氷である私の理解が正しければImがないことを確認)私は枠組みの中で、以下の変更を行ってきたV
道具Serializabe
私が使用できるように、commons-lang3
SerializationUtils
との戻りコピーV value
BitemporalWrapperをclonningとき:
<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 { .. }
今、テストは合格します。あなたが興味を持っていた場合、私は私の変更を共有することができます。