我使用以下框架:我有Hibernate緩存或映射錯誤嗎?
- 休眠4.2.0.Final
- 春3.2.2.RELEASE
- 春數據JPA 1.1.0.RELEASE
- HSQL 2.2.9
- TestNG的6.1.1
我有2個實體:
實體答:
@Entity
@Table(name = "A")
public class A {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "a")
private Set<B> b = new HashSet<B>();
//... getter and setter
}
和實體B:
@Entity
@Table(name = "B")
public class B {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
@JoinColumn(name = "a_id")
private A a;
//... getter and setter
}
和我做了春天的數據JPARepositories他們:
@Repository
public interface ARepository
extends JpaRepository<A, Long> {
}
@Repository
public interface BRepository
extends JpaRepository<B, Long> {
}
,我已經寫了一個測試,看看是否映射作品:
@TransactionConfiguration(defaultRollback = true)
@ContextConfiguration
public class ARepositoryTest
extends AbstractTransactionalTestNGSpringContextTests {
@Inject
@Setter
private ARepository aRepository;
@Inject
@Setter
private BRepository bRepository;
@Test(groups = { "integration" })
public void testSaveWithFeed() {
A a = new A();
aRepository.saveAndFlush(a);
B b = new B();
b.setA(a);
bRepository.saveAndFlush(b);
A findOne = aRepository.findOne(a.getId());
Assert.assertEquals(1, findOne.getB().size());
}
}
但測試失敗:
Hibernate: insert into A (id) values (default)
Hibernate: insert into B (id, a_id) values (default, ?)
FAILED: testSaveWithA
java.lang.AssertionError: expected [1] but found [0]
而我不明白爲什麼。映射中是否存在缺失,或者是否必須清除休眠緩存? 我看到沒有新的選擇查詢,所以hibernate正在緩存A對象 - 但是不應該將引用從A更新到緩存中的Bs?這裏
隨着更多的信息是我的persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="local" transaction-type="RESOURCE_LOCAL" >
</persistence-unit>
</persistence>
我ARepositoryTest-context.xml的
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd">
<context:annotation-config />
<context:component-scan base-package="my.package"/>
<import resource="classpath:/SpringBeans.xml"/>
</beans>
和我SpringBeans.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd">
<context:annotation-config />
<jpa:repositories base-package="my.package.dao" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
</property>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="local"/>
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="generateDdl" value="true" />
<property name="databasePlatform" value="org.hibernate.dialect.HSQLDialect"/>
<property name="database" value="HSQL" />
</bean>
</property>
<property name="jpaPropertyMap">
<map>
<entry key="hibernate.show_sql" value="true" />
</map>
</property>
</bean>
<bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="dataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url" value="jdbc:hsqldb:file:${user.home}/data;shutdown=true" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
</beans>
編輯:增加了版本號,和xml文件
編輯:爲JB Nizet答案 如果我添加到
public void addB(B b) {
this.b.add(b);
}
類和適應的測試用例
@Test(groups = { "integration" })
public void testSaveWithA() {
A a = new A();
aRepository.save(a);
B b = new B();
a.addB(b);
aRepository.saveAndFlush(a);
A findOne = aRepository.findOne(a.getId());
Assert.assertEquals(findOne.getB().size(), 1);
}
測試通過 但HSQL文件中之間沒有任何聯繫A和B:
INSERT INTO A VALUES(1)
INSERT INTO B VALUES(1,NULL)
所以它不會能夠在其他交易中正確選擇它。
如果我在一個
public void addB(B b) {
this.b.add(b);
b.setA(this);
}
沖洗或提交時例外occures拓展新mMethod
java.lang.StackOverflowError
at java.util.HashMap$KeyIterator.<init>(HashMap.java:926)
at java.util.HashMap$KeyIterator.<init>(HashMap.java:926)
at java.util.HashMap.newKeyIterator(HashMap.java:940)
at java.util.HashMap$KeySet.iterator(HashMap.java:974)
at java.util.HashSet.iterator(HashSet.java:170)
at java.util.AbstractSet.hashCode(AbstractSet.java:122)
at org.hibernate.collection.internal.PersistentSet.hashCode(PersistentSet.java:429)
at my.package.A.hashCode(A.java:17)
at my.package.B.hashCode(B.java:13)
at java.util.AbstractSet.hashCode(AbstractSet.java:126)
at org.hibernate.collection.internal.PersistentSet.hashCode(PersistentSet.java:429)
at my.package.A.hashCode(A.java:17)
at my.package.B.hashCode(B.java:13)
...
Linenumbers A.java:17和B.java:13是在@Data Lombok的註釋被放置在生成我的getters和setter。
通過去除依賴性解決龍目爲的hashCode和等於/通過使用Lomboks @EqualsAndHashCode(排除= {「B」})
我在這裏看到你的觀點,但是我沒有完成初始化。我做了一個方法A#addB(B b),並在那裏將b添加到Set中。現在,A和B都存儲在數據庫中,但是B缺少對A的引用。如果我嘗試另外b.setA(a),我碰到了一個java.lang.StackOverflowError我是否缺少了一些東西? – Thomas 2013-04-07 10:21:03
通過編輯問題(addB()和setA())向我們展示這兩種方法的代碼。 – 2013-04-07 10:32:11
我在問題的末尾添加了我的更改 – Thomas 2013-04-07 10:46:23