Java 在Hibernate和Spring中初始化枚举

Java 在Hibernate和Spring中初始化枚举,java,spring,hibernate,spring-mvc,enums,Java,Spring,Hibernate,Spring Mvc,Enums,我有一节简单的课 @Entity @Table(name="user") public class User implements Serializable { @Id @GeneratedValue private Integer Id; @Length(min = 5, message = "Username must be at least 5 characters long.") @Column(name="username",nullable=

我有一节简单的课

@Entity
@Table(name="user")
public class User implements Serializable {

    @Id
    @GeneratedValue
    private Integer Id;
    @Length(min = 5, message = "Username must be at least 5 characters long.")
    @Column(name="username",nullable=false,unique=true)
    private String userName;
    @ManyToMany(cascade= {CascadeType.PERSIST},fetch=FetchType.EAGER)
    @JoinTable(name="user_user_profile")
    private Set<UserProfile> userProfile = new HashSet<>();
}

我将SpringMVC和SpringSecuirty与Hibernate一起使用。是否有任何方法可以在应用程序启动时在
UserProfile
实体中创建所有可能的条目(只有两个)?我是否必须从数据库中获取
UserProfile
(通过
TypedQuery
EntityManager.find()
),然后将其添加到用户中以避免出现任何异常?

枚举项在应用程序中是静态的,因此我不会尝试在数据库中进行自动更改。添加新记录很简单,但删除已被引用的项可能需要单独小心。这些值对于您的应用程序非常重要,因此我认为它们应该包含在您的SQL脚本中


如果您使用的是数据库版本控制工具,如Flyway或Liquibase,请在迁移脚本中添加/删除
user\u profile
表的记录。它们可以配置为在应用程序(和Hibernate)启动之前运行迁移,因此应用程序将始终看到正确的数据。

枚举项在应用程序中是静态的,因此我不会尝试在数据库中进行自动更改。添加新记录很简单,但删除已被引用的项可能需要单独小心。这些值对于您的应用程序非常重要,因此我认为它们应该包含在您的SQL脚本中


如果您使用的是数据库版本控制工具,如Flyway或Liquibase,请在迁移脚本中添加/删除
user\u profile
表的记录。可以将它们配置为在应用程序(和Hibernate)启动之前运行迁移,以便应用程序始终能够看到正确的数据。

您可以添加应用程序启动事件并保留用户配置文件。您也可以在应用程序关闭之前删除所有用户配置文件。但我不建议这样做,因为我假设用户配置文件不会经常更改。如果是这样的话,最好按照另一个答案中的建议,通过一些sql脚本预加载用户配置文件。如果你真的想通过应用程序进行删除,最安全的方法是在应用程序关闭之前删除。下面是示例代码段。我假设您使用的是spring数据jpa,并提供了代码段

@Component
public class AppStartedListener implements ApplicationListener<ContextRefreshedEvent> {

    @Autowired
    private UserProfileRepository repository;

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        for(UserProfileType userProfileType: UserProfileType.values()) {
            UserProfile up = new UserProfile(userProfileType);
            repository.save(up);                
        }      
    }
}


@Component
public class AppStoppedListener implements ApplicationListener<ContextClosedEvent> {

    @Autowired
    private UserProfileRepository repository;

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        repository.deleteAll();
    }
}

public interface UserProfileRepository extends CrudRepository<UserProfile, Integer> {
}
@组件
公共类AppStartedListener实现ApplicationListener{
@自动连线
私有用户档案库;
@凌驾
ApplicationEvent(ContextRefreshedEvent事件)上的公共无效{
对于(UserProfileType UserProfileType:UserProfileType.values()){
UserProfile up=新的UserProfile(userProfileType);
存储库。保存(up);
}      
}
}
@组成部分
公共类AppStoppedListener实现ApplicationListener{
@自动连线
私有用户档案库;
@凌驾
ApplicationEvent(ContextRefreshedEvent事件)上的公共无效{
repository.deleteAll();
}
}
公共接口UserProfileRepository扩展了Crudepository{
}

您可以添加应用程序启动事件并保存用户配置文件。您也可以在应用程序关闭之前删除所有用户配置文件。但我不建议这样做,因为我假设用户配置文件不会经常更改。如果是这样的话,最好按照另一个答案中的建议,通过一些sql脚本预加载用户配置文件。如果你真的想通过应用程序进行删除,最安全的方法是在应用程序关闭之前删除。下面是示例代码段。我假设您使用的是spring数据jpa,并提供了代码段

@Component
public class AppStartedListener implements ApplicationListener<ContextRefreshedEvent> {

    @Autowired
    private UserProfileRepository repository;

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        for(UserProfileType userProfileType: UserProfileType.values()) {
            UserProfile up = new UserProfile(userProfileType);
            repository.save(up);                
        }      
    }
}


@Component
public class AppStoppedListener implements ApplicationListener<ContextClosedEvent> {

    @Autowired
    private UserProfileRepository repository;

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        repository.deleteAll();
    }
}

public interface UserProfileRepository extends CrudRepository<UserProfile, Integer> {
}
@组件
公共类AppStartedListener实现ApplicationListener{
@自动连线
私有用户档案库;
@凌驾
ApplicationEvent(ContextRefreshedEvent事件)上的公共无效{
对于(UserProfileType UserProfileType:UserProfileType.values()){
UserProfile up=新的UserProfile(userProfileType);
存储库。保存(up);
}      
}
}
@组成部分
公共类AppStoppedListener实现ApplicationListener{
@自动连线
私有用户档案库;
@凌驾
ApplicationEvent(ContextRefreshedEvent事件)上的公共无效{
repository.deleteAll();
}
}
公共接口UserProfileRepository扩展了Crudepository{
}

所以我向dao层添加了方法:

@Transactional
@EventListener
public void handleContextRefresh(ContextRefreshedEvent event) {
   UserProfile user=new UserProfile();
   em.persist(user);
   UserProfile admin=new UserProfile();
   admin.setType(UserProfileType.ADMIN);
   em.persist(admin);
}

现在,在添加新用户之前,我只需要使用HQL获取持久的UserProfile对象,我可以将其添加到我的用户中。虽然它可以工作,但我可能会尝试从某种*.sql文件加载它,因为我必须将上面提到的方法添加到Dao层接口(因为接口类型为代理),老实说,我不喜欢它。

所以我将方法添加到Dao层:

@Transactional
@EventListener
public void handleContextRefresh(ContextRefreshedEvent event) {
   UserProfile user=new UserProfile();
   em.persist(user);
   UserProfile admin=new UserProfile();
   admin.setType(UserProfileType.ADMIN);
   em.persist(admin);
}

现在,在添加新用户之前,我只需要使用HQL获取持久的UserProfile对象,我可以将其添加到我的用户中。尽管它可以工作,但我可能会尝试从某种*.sql文件加载它,因为我必须将上面提到的方法添加到Dao层接口(因为接口类型为proxy),老实说,我不喜欢它。

通常我会为spring上下文启动事件添加一个侦听器。当我得到事件时,我会执行所有需要的初始化操作。在这里,您可以找到如何构建侦听器,我建议您使用
@EventListener
注释通常我为spring上下文启动事件添加一个侦听器。当我得到事件时,我会执行所有需要的初始化操作。在这里,您可以找到如何构建侦听器,我建议您使用
@EventListener
注释