我是Hibernate ORM的新手,我想你可以帮助我更好地理解它。更准确地说,我发现自己在想是否能够很好地实现关注点的分离(当然是,我是我无法理解的......但请解释一下)。让我解释一下:在我看来,hibernate的主要目标是允许开发人员处理忘记数据库特性的类。好! 但让我们来看看这个案例:
我有一个对象,假设一个UserDetail与一个Athority对象有一个可能的关系。
@Entity(name="user")
@Table(name="USERS")
public class User implements UserDetails, DomainObject {
private static final long serialVersionUID = 1L;
private long id;
private String username;
private String password;
Collection<Authority> authorities = new ArrayList<Authority>();
public User() {
super();
}
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="id", unique=true, nullable=false)
public long getId() {
return id;
}
//various getters & setters
@OneToMany(mappedBy="user")
public Collection<Authority> getAuthorities() {
return authorities;
}
public void setAuthorities(Collection<Authority> authorities) {
this.authorities = authorities;
}
}
这是权威对象
@Entity(name="authority")
@Table(name="AUTHORITIES")
public class Authority implements GrantedAuthority, DomainObject{
private long id;
private User user;
private String authority; //Spring Security demands them to start with "ROLE_"
public Authority() {
super();
}
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="id", unique=true, nullable=false)
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
@ManyToOne
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Column(name="authority", nullable=false)
public String getAuthority() {
return this.authority;
}
public void setAuthority(String authority) {
this.authority = authority;
}
}
好吧,假设我有一个UserDaoImpl和AuthorityDaoImpl(为简洁起见,这里省略)。如果我想创建一个新的UserDetails并坚持下去,我必须执行以下操作(它是一个inizializer bean,但这里并不重要):
@Component
public class Initializer {
@Autowired
@Qualifier("userDaoImpl")
private UserDao userDao;
@Autowired
@Qualifier("authorityDaoImpl")
private AuthorityDao authorityDao;
@PostConstruct
public void init()
{
if(userDao.loadUserByUsername("admin")==null)
{
System.out.println("starting initialization.");
User admin = new User();
admin.setUsername("admin");
admin.setPassword("admin");
Authority authority = new Authority();
authority.setAuthority("ROLE_ADMIN");
authority.setUser(admin);
admin.getAuthorities().add(authority);
userDao.save(admin);
authorityDao.save(authority);
System.out.println("admin user created.");
}
}
}
好吧,我觉得很奇怪我必须明确调用AuthorityDao来持久保存Authority对象。如果关注点的分离得到了很好的实现,我只需要将authority
对象添加到admin
autority列表中并单独保留管理员。如果我这样做,唯一要保留的实体是管理员。
你不觉得一样吗?我错过了什么吗?
答案 0 :(得分:2)
是。你错过了一件事。只需在cascade = CascadeType.ALL
实体映射中的cascade = CascadeType.PERSIST
映射中添加oneToMany
或Admin
(选择合适),如下所示。完成后,保存adimn
也会保存authority
。
@OneToMany(mappedBy="user", cascade = CascadeType.ALL)
public Collection<Authority> getAuthorities() {
return authorities;
}
请在此处查找有关cascade
类型和设置的详细信息:Hibernate Cascade。
这是支持子实体的不同行为所必需的。例如,您的权限是一个主表,即从国家,货币等表格映射。在这里,您不希望持久/删除货币,国家和父对象。作为通用框架,它必须支持需求的几个方面。
答案 1 :(得分:1)
实际上,可以通过两种不同的方式在映射中启用关联对象的自动持久性:
要表达UML调用的组合(即依赖对象不能独立于引用对象而存在,不被其他对象引用),您可以使其成为@Embeddable。然后,Hibernate将插入,更新和删除依赖对象以及与其拥有对象(关联)。
要表达UML调用聚合的内容(即引用的对象具有自己的身份和独立的生命周期),您可以将引用的对象设为@Entity。您可以通过指定其级联属性来指示JPA自动级联持久性操作。
当然,持久化上下文加载的任何对象都会检测到更改,并在事务提交时自动将它们写入数据库。