«объект ссылается на несохраненный временный экземпляр - сохраните временный экземпляр перед сбросом». Не вызвано INSERT - PullRequest
0 голосов
/ 03 октября 2018

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

** Hibernate: выберите user0_.id в качестве id1_1_, user0_.email в качестве email2_1_, user0_.enabled в качестве enabled3_1_, user0_.first_name в качестве asfirst_na4_1_, user0_.last_name в качестве last_nam5_1_, user0_.password в качестве пароля6_1_, user0_.phone в качестве phone7_1_, user0_.username в качестве username8_1_ от пользователя user0_, где user0_.username =?

Hibernate: роль role0_______ роли_0__ роль.name, как name2_0_1_, userroles1_.role_role_id как role_rol2_2_3_, userroles1_.user_role_id как user_rol1_2_3_, userroles1_.user_role_id как user_rol1_2_0_, userroles1_.role_role_id как role_rol2_2_0_, userroles1_.user_id как user_id3_2_0_ от роли role0_ левое внешнее соединение USER_ROLE userroles1_ на role0_.role_id = userroles1_.role_role_idгде role0_.role_id =?

Hibernate: выберите next_val в качестве id_val из hibernate_sequence дляобновление **

Я обнаружил, что причиной этого исключения является то, что когда пользователь должен быть сохранен, Роль не заканчивает сохранение.

Я добавляю данные жестким кодом с помощью roleRepository и userRepositoryнапрямую, и это работает.

Я хочу знать, как позволить пользователю сохранять после завершения сохранения роли.

Ответы [ 2 ]

0 голосов
/ 03 октября 2018

Вы можете использовать каскад Все на сущности UserRole для сопоставления роли многие-к-одному, и вы можете сделать то же самое в вашей сущности пользователя.вам не нужно вызывать roleRepository и userRepository, тогда вам просто нужно вызвать userRepository и установить значения для роли пользователя в user и роли в userRole.

Также для вашей ошибки вы должны добавить тип Generationкак Авто на @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;
}
0 голосов
/ 03 октября 2018

Если вы не поддерживаете какую-либо последовательность в базе данных, тогда используйте @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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...