在启动应用程序时,我想添加名为ADMIN的数据客户和到Role表。同时,我想创建一个USER并给这个USER管理的角色。但是正如你所看到的,当我想将角色字段设置为USER时实体,它给出一个错误。如果我删除用户实体上的角色字段分配,它不会给出错误。我是否尝试将此角色信息分配给用户而不将其保存到数据库中?所有这些事务都发生在单个事务中吗?有什么问题吗?
@RequiredArgsConstructor
@Component
public class AppStartupRunner implements ApplicationRunner {
private final RoleRepository roleRepository;
private final BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
private final UserRepository userRepository;
@Override
public void run(ApplicationArguments args) throws Exception {
Role role = new Role();
role.setName("ADMIN");
Role role2 = new Role();
role2.setName("CUSTOMER");
roleRepository.save(role);
roleRepository.save(role2);
User user = new User();
user.setUserStatus(UserStatus.ACTIVE);
user.setUserType(UserType.ADMIN);
user.setPhoneNumber("05365785476");
user.setPassword(bCryptPasswordEncoder.encode("123456789e"));
user.setEmail("emirhan@gmail.com");
user.setName("Emirhan Ay");
user.getRoles().add(role);
user.setCreatedAt(new Date());
userRepository.save(user);
}
}
java.lang.IllegalStateException: Failed to execute ApplicationRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:771) ~[spring-boot-2.6.7.jar:2.6.7]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:758) ~[spring-boot-2.6.7.jar:2.6.7]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:310) ~[spring-boot-2.6.7.jar:2.6.7]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1312) ~[spring-boot-2.6.7.jar:2.6.7]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301) ~[spring-boot-2.6.7.jar:2.6.7]
at com.example.bankapp.BankApplication.main(BankApplication.java:10) ~[classes/:na]
Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist: com.example.bankapp.entity.Role; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: com.example.bankapp.entity.Role
更新!我找到了这样的解决方案->我创建了一个数据。app/resources文件夹中的SQL文件。我在我的应用程序属性文件中添加了以下设置。
spring.jpa.defer-datasource-initialization=true
spring.sql.init.mode=always
INSERT INTO ROLE (name) VALUES ('ADMIN');
INSERT INTO ROLE (name) VALUES ('CUSTOMER');
INSERT INTO USER (email,password,name,phone_number,user_type,user_status,is_deleted,created_at)
VALUES ('emirhan@gmail.com','$2a$10$ReWLWNLk6iSPWZ1z6tVv1efkk0qgONxAoZaD6BJ8I80qe0ykfLqma',
'Emirhan Ay','05365785476','ADMIN','ACTIVE','false','2022-06-01 23:27:03.534');
INSERT INTO USER_ROLE (user_id,role_id) VALUES ('1','1')
您这里所拥有的实际上是工作的,但是您的错误表明您没有正确地持久化它。分离的实体是因为您正在尝试持久化角色,而该角色本身尚未持久化。
试试这样
…
Role persistedRole = roleRepository.save(role);
…
user.getRoles().add(persistedRole);
另外,请注意,在您当前的逻辑中,您没有对role2
进行任何操作,但如果您想将其附加到User
,则需要对其进行相同的操作。
正如其他人所提到的,我倾向于使用其他Spring方法来预填充数据库,除非您打算添加逻辑以确保每次启动应用程序时不会在数据库中重新创建这些记录。