Чтобы изначально заполнить базу данных данными, я создал экземпляры сущностей и написал класс обслуживания, который должен сохранить их в базе данных.Как сохранить исходные данные с помощью JpaRepository
В очень упрощенном виде, моя модель состоит из трех классов A, B и C. экземпляры классов А и В обоих эталонных (одни и те же) экземпляры C (аннотированные с @ManyToOne
):
a1 -> c1
a2 -> c2
a3 -> c1
b1 -> c1
b2 -> c2
Для A и BI используйте 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));
но сдвигает только моя проблема, как исключение, то происходит во второй строке, когда b1, который ссылается на уже сохраненный c1 должен получить спасение.
Как сохранить структуры данных, созданные мной одним способом, не получая это исключение?
Вот остальная часть кода:
@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();
}
}
}
Суперкласс для теста я нашел где-то в Интернете, и модифицировали его немного:
@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();
}
}
Если вы хотите бегущую версию кода - Я проверил его здесь:
https://github.com/BernhardBln/stackexchange
Это проект maven.
Не могли бы вы показать код, который инициализирует экземпляры А1-3 и c1, c2? – PepperBob
Я добавил его, а также ссылку на github, где я поставил пример для запуска – Bernhard