UserRole.java:
@Entity
@Table(name="user_role")
public class UserRole implements Serializable {
private static final long serialVersionUID = 890345L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long userRoleId;
public UserRole () {}
public UserRole (User user, Role role) {
this.user = user;
this.role = role;
}
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "user_id")
private User user;
@ManyToOne(fetch = FetchType.EAGER)
private Role role;
public long getUserRoleId() {
return userRoleId;
}
Role.java:
@Entity
public class Role implements Serializable{
private static final long serialVersionUID = 890245234L;
@Id
private int roleId;
private String name;
@OneToMany(mappedBy = "role", cascade = CascadeType.ALL)
private Set<UserRole> userRoles = new HashSet<>();
public Role(){}
public int getRoleId() {
return roleId;
}
UserServiceImpl.java:
@Service
public class UserServiceImpl implements UserService{
private static final Logger LOG = LoggerFactory.getLogger(UserService.class);
@Autowired
private UserRepository userRepository;
@Autowired
private RoleRepository roleRepository;
@Transactional
public User createUser(User user, Set<UserRole> userRoles) {
User localUser = userRepository.findByUsername(user.getUsername());
if(localUser != null) {
LOG.info("User with username {} already exist. Nothing will be done. ", user.getUsername());
} else {
for (UserRole ur : userRoles) {
//too slow here
roleRepository.save(ur.getRole());
}
user.getUserRoles().addAll(userRoles);
localUser = userRepository.save(user);
}
return localUser;
}
}
工作硬代码:
@Override
public void run(String... args) throws Exception {
User user1 = new User();
user1.setFirstName("John");
user1.setLastName("Adams");
user1.setUsername("j");
user1.setPassword(SecurityUtility.passwordEncoder().encode("p"));
user1.setEmail("JAdams@gmail.com");
Set<UserRole> userRoles = new HashSet<>();
Role role1 = new Role();
role1.setRoleId(1);
role1.setName("ROLE_USER");
//here it save the role data
roleRepository.save(role1);
userRoles.add(new UserRole(user1, role1));
user1.setUserRoles(userRoles);
userRepository.save(user1);
异常跟踪:
2018-10-02 16:08:51.251 INFO 19624 --- [ main] com.example.demo.ServerApplication : Started ServerApplication in 2.161 seconds (JVM running for 2.526)
2018-10-02 16:08:51.521 INFO 19624 --- [ main] o.h.h.i.QueryTranslatorFactoryInitiator : HHH000397: Using ASTQueryTranslatorFactory
Hibernate: select user0_.id as id1_1_, user0_.email as email2_1_, user0_.enabled as enabled3_1_, user0_.first_name as first_na4_1_, user0_.last_name as last_nam5_1_, user0_.password as password6_1_, user0_.phone as phone7_1_, user0_.username as username8_1_ from user user0_ where user0_.username=?
Hibernate: select role0_.role_id as role_id1_0_1_, role0_.name as name2_0_1_, userroles1_.role_role_id as role_rol2_2_3_, userroles1_.user_role_id as user_rol1_2_3_, userroles1_.user_role_id as user_rol1_2_0_, userroles1_.role_role_id as role_rol2_2_0_, userroles1_.user_id as user_id3_2_0_ from role role0_ left outer join user_role userroles1_ on role0_.role_id=userroles1_.role_role_id where role0_.role_id=?
Hibernate: select next_val as id_val from hibernate_sequence for update
2018-10-02 16:08:51.594 ERROR 19624 --- [ main] o.hibernate.id.enhanced.TableStructure : could not read a hi value - you need to populate the table: hibernate_sequence
2018-10-02 16:08:51.607 INFO 19624 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2018-10-02 16:08:51.611 ERROR 19624 --- [ main] o.s.boot.SpringApplication : Application run failed
java.lang.IllegalStateException: Failed to execute CommandLineRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:821) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:802) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:341) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1277) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1265) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at com.example.demo.ServerApplication.main(ServerApplication.java:32) [classes/:na]
Caused by: org.springframework.orm.jpa.JpaSystemException: could not read a hi value - you need to populate the table: hibernate_sequence; nested exception is org.hibernate.id.IdentifierGenerationException: could not read a hi value - you need to populate the table: hibernate_sequence
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:312) ~[spring-orm-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:223) ~[spring-orm-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:527) ~[spring-orm-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61) ~[spring-tx-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242) ~[spring-tx-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:153) ~[spring-tx-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:135) ~[spring-data-jpa-2.0.10.RELEASE.jar:2.0.10.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) ~[spring-aop-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61) ~[spring-data-commons-2.0.10.RELEASE.jar:2.0.10.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at com.sun.proxy.$Proxy87.save(Unknown Source) ~[na:na]
at com.example.demo.Service.Impl.UserServiceImpl.createUser(UserServiceImpl.java:40) ~[classes/:na]
at com.example.demo.Service.Impl.UserServiceImpl$$FastClassBySpringCGLIB$$a970b40f.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:746) ~[spring-aop-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294) ~[spring-tx-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98) ~[spring-tx-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688) ~[spring-aop-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at com.example.demo.Service.Impl.UserServiceImpl$$EnhancerBySpringCGLIB$$7f8e6119.createUser(<generated>) ~[classes/:na]
at com.example.demo.ServerApplication.run(ServerApplication.java:49) [classes/:na]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:818) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
... 5 common frames omitted
Caused by: org.hibernate.id.IdentifierGenerationException: could not read a hi value - you need to populate the table: hibernate_sequence
at org.hibernate.id.enhanced.TableStructure$1$1.execute(TableStructure.java:142) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.id.enhanced.TableStructure$1$1.execute(TableStructure.java:126) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.jdbc.WorkExecutor.executeReturningWork(WorkExecutor.java:55) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.jdbc.AbstractReturningWork.accept(AbstractReturningWork.java:34) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcIsolationDelegate.delegateWork(JdbcIsolationDelegate.java:57) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.id.enhanced.TableStructure$1.getNextValue(TableStructure.java:125) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.id.enhanced.NoopOptimizer.generate(NoopOptimizer.java:40) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.id.enhanced.SequenceStyleGenerator.generate(SequenceStyleGenerator.java:452) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:105) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.jpa.event.internal.core.JpaPersistEventListener.saveWithGeneratedId(JpaPersistEventListener.java:67) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:189) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:132) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:58) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:783) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:768) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Unknown Source) ~[na:na]
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:305) ~[spring-orm-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at com.sun.proxy.$Proxy85.persist(Unknown Source) ~[na:na]
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:490) ~[spring-data-jpa-2.0.10.RELEASE.jar:2.0.10.RELEASE]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Unknown Source) ~[na:na]
at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:377) ~[spring-data-commons-2.0.10.RELEASE.jar:2.0.10.RELEASE]
at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:200) ~[spring-data-commons-2.0.10.RELEASE.jar:2.0.10.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:641) ~[spring-data-commons-2.0.10.RELEASE.jar:2.0.10.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:605) ~[spring-data-commons-2.0.10.RELEASE.jar:2.0.10.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:590) ~[spring-data-commons-2.0.10.RELEASE.jar:2.0.10.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59) ~[spring-data-commons-2.0.10.RELEASE.jar:2.0.10.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294) ~[spring-tx-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98) ~[spring-tx-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139) ~[spring-tx-5.0.9.RELEASE.jar:5.0.9.RELEASE]
... 26 common frames omitted
**休眠状态:选择user0_.id作为id1_1_,user0_.email作为电子邮件2_1_,user0_.enabled被启用3_1_,user0_.first_name作为first_na4_1_,user0_.last_name作为last_nam5_1_,user0_.password作为password6_1_,user0_.phone作为phone7_1_, user0_.username作为用户名user8_中的username8_1_,其中user0_.username =?
休眠:选择role0_.role_id作为role_id1_0_1_,role0_.name作为名称2_0_1_,userroles1_.role_role_id作为role_rol2_2_3_,userroles1_.user_role_id作为user_rol1_2_3_,userroles1_.user_role_id_1作为user_rol1_2_3_,userroles1_.user_role_id_1作为user_rol1_2_3_,在角色0_.role_id = userroles1_.role_role_id上向左外部加入user_role userroles1_,其中role0_.role_id =?
休眠:从hibernate_sequence中选择next_val作为id_val进行更新**
我发现发生此异常的原因是,当需要保存用户时,角色尚未完成保存。
我直接通过具有roleRepository和userRepository的硬代码添加数据,并且可以正常工作。
我想知道如何在角色完成保存后让用户保存。
答案 0 :(得分:0)
如果您不维护数据库中的任何序列,请使用@GeneratedValue(strategy = javax.persistence.GenerationType.IDENTITY )
,它将自动为您的表维护唯一的标识。
对于用户角色实体,请在下面使用:
@Entity
@Table(name="user_role")
public class UserRole implements Serializable {
private static final long serialVersionUID = 890345L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long userRoleId;
答案 1 :(得分:0)
您可以在UserRole实体上使用层叠All进行多对一的角色映射,并且可以在用户实体中执行相同的操作。您不必调用roleRepository和userRepository,则只需调用userRepository并为user中的用户角色和userRole中的角色设置值。
同样,对于错误,您还必须在“角色”实体中的@Id上将“生成类型”添加为“自动”。
@Entity
@Table(name="user_role")
public class UserRole implements Serializable {
private static final long serialVersionUID = 890345L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long userRoleId;
public UserRole () {}
public UserRole (User user, Role role) {
this.user = user;
this.role = role;
}
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "user_id")
private User user;
@ManyToOne(fetch = FetchType.EAGER,cascade = CascadeType.ALL)
private Role role;
public long getUserRoleId() {
return userRoleId;
}