1

我是 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对象添加到admin权限列表并单独保留管理员即可。如果我这样做,唯一要保留的实体是管理员。你不觉得一样吗?我错过了什么吗?

4

2 回答 2

2

是的。你错过了一件事。只需在实体映射中的映射中添加cascade = CascadeType.ALLcascade = CascadeType.PERSIST(选择合适的),如下所示。完成后,保存也将保存。oneToManyAdminadimnauthority

     @OneToMany(mappedBy="user", cascade = CascadeType.ALL)
     public Collection<Authority> getAuthorities() {
            return authorities;
     }

请在cascade此处找到有关类型和设置的更多详细信息:Hibernate Cascade

这是支持子实体上的不同行为所必需的。例如,您的权限是一个主表,即从国家、货币等表映射。在这里,您不希望保留/删除货币、国家和父对象。作为一个通用框架,它必须支持需求的几个方面。

于 2012-10-20T17:17:05.100 回答
1

实际上,可以通过两种不同的方式在映射中启用关联对象的自动持久性:

为了表达 UML 所说的组合(即依赖对象不能独立于引用对象而存在,不能被其他对象引用),您可以将其设为 @Embeddable。然后 Hibernate 将插入、更新和删除依赖对象及其所属对象(关联到)。

为了表达 UML 所称的聚合(即,被引用对象具有自己的身份和独立的生命周期),您将被引用对象设为 @Entity。您可以通过指定其级联属性来指示 JPA 沿关联自动级联持久性操作。

当然,持久化上下文加载的任何对象都会检测到变化,并在事务提交时自动将它们写入数据库。

于 2012-10-20T17:38:15.810 回答