【问题标题】:hibernate many to one mapping, should I insert this way?休眠多对一映射,我应该这样插入吗?
【发布时间】:2012-11-02 16:11:48
【问题描述】:

假设我们有两个表,userdomain。用户可能有一个域,一个域可能有多个用户。所以我们将做单向多对一:

@Entity
@Table(name = "DOMAIN")
public class Domain implements Serializable
{
    @Id
    @Column(name = "DOMAIN_ID")
    private Integer domainId;

    @Column(name = "NAME")
    private String domainName;
}

@Entity
@Table(name = "\"USER\"")
public class User implements Serializable
{
    @Id
    @GeneratedValue(generator = "USER_SEQ")
    @GenericGenerator(name = "USER_SEQ", strategy = "sequence", parameters = @Parameter(name = "sequence", value = "SEQ_USER_ID"))
    @Column(name = "USER_ID", nullable = false)
    private Long userId;

    @Column(name = "FIRST_NAME")
    private String firstName;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "DOMAIN_ID")
    @ForeignKey(name = "DOMAIN_ID")
    private Domain domain;
}

Domain 表是不可更改的,字典。而User 是可编辑的表格。

我正在创建一个基本表单,用户可以在其中选择将在其中创建新用户的域。假设我的控制器收到了这些数据:

Integer domainId = 1;
String firstName = "aaa";

所以我正在创建新用户:

User newUser = new User();
newUser.setFirstName( firstName );

现在我的问题来了,我应该这样做吗?

Domain domain = somthingThatWillFetchObjectFromDb.getDomain( domainId );
newUser.setDomain( domain );
//save user

这将生成额外的选择,以获取域。当然我可以用Integer domainId代替POJO,但这不是ORM。那么问题又来了,这是应该的方式吗?

【问题讨论】:

    标签: java hibernate orm


    【解决方案1】:

    是的,这就是你应该做的。如果您不想实际从数据库中加载域信息,请使用名称奇怪的Session.load() 方法而不是Session.get() 方法。如果域尚未加载到会话中,Session.load() 将简单地为您返回该域的统一实体代理(就像您加载了一些与域的惰性关联的实体一样),而不会访问数据库。

    也就是说,如果域是不可更改的,为什么要在域字段上设置@Cascade(CascadeType.ALL)?这意味着每次您合并或更新用户时,域也将被合并或更新。更糟糕的是:如果您删除一个用户,该域也将被删除(如果其他用户引用同一域,这当然会导致异常)。

    【讨论】:

    • 当然它不应该在那里,我粘贴时的错误:) 两个对象都比这里大得多
    【解决方案2】:

    是的。要保存User 这样的子实体,您需要在其中设置父实体,即Domain 实体。

    另一种方法是在父实体中定义双向映射(OneToMany),即。域,加载Domain,在Domain 中添加一个或多个User 对象并仅保存Domain 实体,例如

    Domain实体:

      @OneToMany(fetch = FetchType.LAZY, mappedBy = "domain")
      List<User> users = null;
    
      public List<User> getUsers(){
         return this.users;
      }
    
      public void setUsers(List<User> user){
         this.users = users;
      }
    
      public void addUser(User user){
         user.setDomain(this);//set the parent entity
         if(this.users==null){
            this.users = new ArrayList<User>();
         }
         this.user.add(user);
      }
    

    然后拯救用户:

       User user1 = new User();
       ......
       User user2 = new User();
       ......
       Domain domain = loadDomain();//<- use actual method to load the domain
       //< add all the users to be saved at once
       domain.addUser(user1); 
       domain.addUser(user2);
       //save parent entity i.e. domain
       saveDomain(domain);//use actual method to save the entity
    

    【讨论】:

      猜你喜欢
      • 2011-04-07
      • 1970-01-01
      • 2019-02-19
      • 1970-01-01
      • 1970-01-01
      • 2013-12-02
      • 2021-11-11
      • 1970-01-01
      相关资源
      最近更新 更多