gpt4 book ai didi

java - 如何使用 JpaRepository 保存初始数据

转载 作者:行者123 更新时间:2023-12-02 06:30:05 25 4
gpt4 key购买 nike

为了最初用数据填充数据库,我创建了实体实例并编写了一个服务类来将它们保存在数据库中。

以一种非常简单的方式,我的模型由三个类 A、B 和 C 组成。A 类和 B 类的实例都引用(相同的)C 实例(用 @ManyToOne 注释) ):

a1 -> c1
a2 -> c2
a3 -> c1

b1 -> c1
b2 -> c2

对于 A 和 B,我使用 JpaRepositories 进行持久化。

然后我尝试保存以编程方式创建的实例:

@Transactional
public void save(A a1, A a2, A a3, B b1, B b2) {
aRepo.save(a1);
aRepo.save(a2);
aRepo.save(a3);

bRepo.save(b1);
bRepo.save(b2);
}

我在第三行中遇到异常(“分离的实体传递给持久化:C”),因为实例 c1 已保存在第一行中。

我怎样才能避免这种情况?我认为在我的服务中使用 @Transactional 标记我的保存方法就足够了,但显然事实并非如此。

当然我可以直接写

aRepo.save(Arrays.asList(a1, a2, a3));
bRepo.save(Arrays.asList(b1, b2));

但这只会改变我的问题,因为当引用已保存的 c1 的 b1 应该被保存时,第二行会发生异常。

如何保存在一种方法中创建的数据结构而不出现该异常?

这是其余的代码:

@Entity
public class A {

@Id
@GeneratedValue
@Access(AccessType.FIELD)
private Long id;

@ManyToOne(cascade = CascadeType.ALL)
@Access(AccessType.FIELD)
private C c;

public A(C c) {
this.c = c;
}

public C getC() {
return c;
}
}

B 类看起来完全一样,C 类只包含 ID 参数。

实例是在测试用例中创建的:

public class DBTest extends AbstractH2TestCase {

@Test
public void testDataStorage() {

final AbstractApplicationContext context = new AnnotationConfigApplicationContext(DBTest.class);

try {
final PersistService persistService = context.getBean(PersistService.class);

C c1 = new C();
C c2 = new C();

A a1 = new A(c1);
A a2 = new A(c2);
A a3 = new A(c1);

B b1 = new B(c1);
B b2 = new B(c2);

persistService.save(b1, b2, a1, a2, a3);

} finally {
context.close();
}
}
}

我在网络上找到了测试的父类(super class)并对其进行了一些修改:

@Configuration
@ComponentScan(basePackageClasses = A.class)
@EnableJpaRepositories
public class AbstractH2TestCase {

public AbstractH2TestCase() {
super();
}

@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder().setType(H2).build();
}

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource,
JpaVendorAdapter jpaVendorAdapter) {

final LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();

lef.setDataSource(dataSource);
lef.setJpaVendorAdapter(jpaVendorAdapter);

final String thisPackageAndSubpackages = this.getClass().getPackage().getName();
lef.setPackagesToScan(thisPackageAndSubpackages);

return lef;
}

@Bean
public JpaVendorAdapter jpaVendorAdapter() {

final HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();

hibernateJpaVendorAdapter.setShowSql(false);
hibernateJpaVendorAdapter.setGenerateDdl(true);
hibernateJpaVendorAdapter.setDatabase(Database.H2);

return hibernateJpaVendorAdapter;
}

@Bean
public PlatformTransactionManager transactionManager() {
return new JpaTransactionManager();
}

}

如果您想要代码的运行版本 - 我在这里 checkin 了它:

https://github.com/BernhardBln/stackexchange

这是一个 Maven 项目。

最佳答案

你失踪了

@EnableTransactionManagement

关于你的 DBTest 类

    @EnableTransactionManagement
public class DBTest extends AbstractH2TestCase {

关于java - 如何使用 JpaRepository 保存初始数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20148343/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com