玩!框架:如何将父类中的实体提升为子类

时间:2012-02-06 18:45:58

标签: hibernate playframework

假设我有一个对用户操作进行审计的系统: 就像一个名叫XXX的用户做了一杯茶,然后做了......,然后做了......

所以有一个UserActions表(userId,actionId)

现在用户已婚并且 - 在我的系统中 - 现在他可以有孩子,所以我想将正常的用户实体推广到已经拥有子女列表(其他普通用户实体)的已婚用户实体

像: 具体的母体实体:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class User extends Model {
}

具体的子实体:

@Entity
public class MarriedUser extends User {
    @OneToMany()
    public List<User> children;
}

我的问题是如何在控制器中编写代码以将数据库中的实体从父(User)升级到子(MarriedUser) - 通常这是通过在数据库中插入新记录来完成的。 MarriedUser表与用户的Id相同(因为我正在使InheritanceType加入)所以在数据库中它很简单,但是hibernate代码是我不知道的。

我告诉你审计信息,因为我不能删除用户XXX并创建一个带有新ID的新结果用户,我需要它具有相同的ID。

所以请帮助我使用hibernate代码......

2 个答案:

答案 0 :(得分:2)

我认为你因为滥用继承而面临问题。

您不能在不丢失对象标识的情况下更改对象的类型,因此您不应该使用继承来表示同一对象的不同状态,就像您尝试的那样。

您可以使用单独的对象来表示User的婚姻状况:

@Entity 
public class User extends Model {
    @OneToOne
    public Marriage marriage;
    ...
}

@Entity 
public class Marriage extends Model {
    @OneToMany()
    public List<User> children; 
}

或者,您可以将children移至User,并根据需要使用一些标记来表示婚姻状况。

是的,据我所知,没有办法改变Hibernate中现有实体的类型。

答案 1 :(得分:0)

我相信你正以错误的方式接近你的问题。你在这里有一个'state machine',其中一个实体(你的用户)可以处于允许/禁止某些动作的某些状态。

通过去掉实体的状态及其存储,您可能会获得更多成功。使用枚举(或类似)存储状态,然后在尝试触发模型上的操作时检查状态是否正确。如果它不是有效状态,则引发异常。

您的用户界面应根据状态代码限制可用操作的范围。

@Entity 
 public class User extends Model {

    // this status code could be an enum, or any other type that fits
    public int statusCode;

    ...

    public void action() {
        if(statusCode != 1){
          throw new IllegalStateException("State 1 required for this action");
        }
        //code for action
    }
 }