2017-08-09 96 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文件加載它,因爲我必須將上述方法添加到道層接口(因爲接口類型代理),我不喜歡它是誠實的。