2017-08-09 72 views
0

初始化枚举我有一个简单的类在Hibernate和Spring

@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<>(); 
} 

,二类:

@Entity 
@Table(name = "user_profile") 
public class UserProfile { 
    @javax.persistence.Id 
    @GeneratedValue 
    private int Id; 

    @Column(name = "type", nullable = false, unique = true) 
    @Enumerated(EnumType.STRING) 
    private UserProfileType type = UserProfileType.USER; 
} 

public enum UserProfileType { 
    USER("USER"), 
    ADMIN("ADMIN"); 
} 

我使用Spring MVC和春天Secuirty与Hibernate。有什么办法可以在应用程序启动时使每个可能的条目都在UserProfile实体(只有两个)?我是否必须从数据库获取UserProfile(通过TypedQueryEntityManager.find()),然后将其添加到用户以避免发生任何异常?

+0

通常我为spring上下文启动事件添加一个监听器。当我得到事件时,我会做所有我需要的初始化操作。在这里你可以找到如何构建监听器https://spring.io/blog/2015/02/11/better-application-events-in-spring-framework-4-2我建议你使用'@ EventListener'注解 –

回答

1

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

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

1

您可以添加应用程序启动事件并保留用户配置文件。您也可以在应用程序关闭之前删除所有用户配置文件。但我不会推荐这个,因为我认为UserProfiles不会经常更改。如果是这样的话,您最好通过其他答案中建议的方式通过一些sql脚本预加载用户配置文件。如果你真的想通过应用程序来做到这一点,最安全的方式是在应用程序关闭之前删除它。以下是示例代码片段。我假设你使用spring-data-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> { 
} 
0

所以我添加方法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得到持续的用户配置对象,我可以添加到我的用户面前。尽管它的工作原理,我可能会尝试从某种* .sql文件加载它,因为我必须将上述方法添加到道层接口(因为接口类型代理),我不喜欢它是诚实的。