Код: Выделить всё
import com.fasterxml.jackson.databind.*;
import org.springframework.context.annotation.*;
import org.springframework.core.io.*;
import org.springframework.data.repository.init.*;
@Configuration
public class RepositoryDataInitializer {
protected Resource[] getResources() {
return new Resource[]{
new ClassPathResource("initial-data/permission.json"),
new ClassPathResource("initial-data/permission-set.json"),
new ClassPathResource("initial-data/user.json"),
new ClassPathResource("initial-data/user-group.json"),
};
}
@Bean
public Jackson2RepositoryPopulatorFactoryBean securityRepositoryPopulator() {
var factory = new Jackson2RepositoryPopulatorFactoryBean();
factory.setResources(getResources());
factory.setMapper(new ObjectMapper()
.findAndRegisterModules()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
);
return factory;
}
}
Код: Выделить всё
// permission.json
[{
"_class": "org.ximinghui.study.permission.Permission",
"name": "CREATE_ACCOUNT",
"description": "Ability to create an account"
}, {
"_class": "org.ximinghui.study.permission.Permission",
"name": "CREATE_PERMISSION"
}]
// permission-set.json
[{
"_class": "org.ximinghui.study.permission.PermissionSet",
"ownerAccount": "123",
"number": 1,
"name": "SecurityAdmin",
"permissions": [{
"name": "CREATE_ACCOUNT"
}]
}, {
"_class": "org.ximinghui.study.permission.PermissionSet",
"ownerAccount": "123",
"number": 2,
"name": "InitializationTest",
"permissions": ["CREATE_ACCOUNT", "CREATE_PERMISSION"]
}]
// user.json
[{
"_class": "org.ximinghui.study.user.User",
"ownerAccount": "123",
"userId": "8f3e",
"username": "ximinghui",
"password": "123456",
"firstName": "Xi",
"lastName": "Minghui",
"sex": "MALE",
"birthday": "1998-01-01",
"lastLoginTime": "2024-11-04T23:27:31+00:00",
"userGroups": [],
"permissions": ["CREATE_ACCOUNT"],
"permissionSets": [{
"ownerAccount": "123",
"number": 2
}],
"isEnabled": true
}]
// user-group.json
[{
"_class": "org.ximinghui.study.user.UserGroup",
"ownerAccount": "123",
"groupNumber": 1,
"groupName": "Guests",
"members": [{
"ownerAccount": "123",
"userId": "8f3e"
}],
"permissions": ["CREATE_ACCOUNT"],
"permissionSets": [{
"ownerAccount": "123",
"number": 2
}]
}]
объект ссылается на несохраненный временный экземпляр — сохраните временный экземпляр перед очисткой
Код: Выделить всё
org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: org.ximinghui.study.user.User
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:368) ~[spring-orm-6.1.10.jar:6.1.10]
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:246) ~[spring-orm-6.1.10.jar:6.1.10]
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:566) ~[spring-orm-6.1.10.jar:6.1.10]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:795) ~[spring-tx-6.1.10.jar:6.1.10]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:758) ~[spring-tx-6.1.10.jar:6.1.10]
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:676) ~[spring-tx-6.1.10.jar:6.1.10]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:426) ~[spring-tx-6.1.10.jar:6.1.10]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:138) ~[spring-tx-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:165) ~[spring-data-jpa-3.3.1.jar:3.3.1]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:223) ~[spring-aop-6.1.10.jar:6.1.10]
at jdk.proxy2/jdk.proxy2.$Proxy157.save(Unknown Source) ~[na:na]
at org.springframework.data.repository.support.CrudRepositoryInvoker.invokeSave(CrudRepositoryInvoker.java:85) ~[spring-data-commons-3.3.1.jar:3.3.1]
at org.springframework.data.repository.init.ResourceReaderRepositoryPopulator.persist(ResourceReaderRepositoryPopulator.java:160) ~[spring-data-commons-3.3.1.jar:3.3.1]
at org.springframework.data.repository.init.ResourceReaderRepositoryPopulator.populate(ResourceReaderRepositoryPopulator.java:121) ~[spring-data-commons-3.3.1.jar:3.3.1]
at org.springframework.data.repository.init.AbstractRepositoryPopulatorFactoryBean.onApplicationEvent(AbstractRepositoryPopulatorFactoryBean.java:93) ~[spring-data-commons-3.3.1.jar:3.3.1]
at org.springframework.data.repository.init.AbstractRepositoryPopulatorFactoryBean.onApplicationEvent(AbstractRepositoryPopulatorFactoryBean.java:38) ~[spring-data-commons-3.3.1.jar:3.3.1]
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:185) ~[spring-context-6.1.10.jar:6.1.10]
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:178) ~[spring-context-6.1.10.jar:6.1.10]
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:156) ~[spring-context-6.1.10.jar:6.1.10]
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:451) ~[spring-context-6.1.10.jar:6.1.10]
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:384) ~[spring-context-6.1.10.jar:6.1.10]
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:984) ~[spring-context-6.1.10.jar:6.1.10]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:627) ~[spring-context-6.1.10.jar:6.1.10]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.3.1.jar:3.3.1]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) ~[spring-boot-3.3.1.jar:3.3.1]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456) ~[spring-boot-3.3.1.jar:3.3.1]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:335) ~[spring-boot-3.3.1.jar:3.3.1]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1363) ~[spring-boot-3.3.1.jar:3.3.1]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1352) ~[spring-boot-3.3.1.jar:3.3.1]
at com.lptcorporation.audit.Main.main(Main.java:10) ~[classes/:na]
Caused by: java.lang.IllegalStateException: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: org.ximinghui.study.user.User
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:157) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:167) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:173) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1429) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:487) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:2324) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:1981) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:439) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:169) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:267) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:101) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:562) ~[spring-orm-6.1.10.jar:6.1.10]
... 33 common frames omitted
Caused by: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: org.ximinghui.study.user.User
at org.hibernate.metamodel.mapping.EntityIdentifierMapping.getIdentifierIfNotUnsaved(EntityIdentifierMapping.java:106) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
at org.hibernate.metamodel.mapping.internal.EmbeddedForeignKeyDescriptor.getAssociationKeyFromSide(EmbeddedForeignKeyDescriptor.java:622) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
at org.hibernate.metamodel.mapping.internal.ManyToManyCollectionPart.decompose(ManyToManyCollectionPart.java:205) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
at org.hibernate.persister.collection.BasicCollectionPersister.applyInsertRowValues(BasicCollectionPersister.java:450) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
at org.hibernate.persister.collection.mutation.InsertRowsCoordinatorStandard.insertRows(InsertRowsCoordinatorStandard.java:109) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
at org.hibernate.persister.collection.BasicCollectionPersister.recreate(BasicCollectionPersister.java:119) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
at org.hibernate.action.internal.CollectionRecreateAction.execute(CollectionRecreateAction.java:47) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:632) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:499) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:371) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:41) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:127) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1425) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
... 41 common frames omitted
Я попытался поставить пользователя первым в классе конфигурации, но это не сработало, и я получил ту же ошибку. И есть интересный феномен: если я закомментирую код new ClassPathResource("initial-data/user-group.json") и попытаюсь запустить, проект может завершить работу по инициализации данных, а затем раскомментировать и пытаюсь запустить, получаю сообщение об ошибке.
Я думаю, что если я смогу управлять RepositoryPopulator, чтобы он сохранялся в порядке Permission, PermissionSet, User, UserGroup, Я могу решить эту проблему или мои мысли в неправильном направлении?
Спасибо большое за любую информацию!
Подробнее здесь: https://stackoverflow.com/questions/791 ... -populator