假设我们有两个表,user
和domain
。用户可以拥有一个域,一个域可以用于许多用户。所以我们会做多对一的单向:
@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。再问一遍,问题应该是这样吗?
答案 0 :(得分:3)
是的,那就是你应该做的。如果您不想从数据库中实际加载域信息,请使用奇怪命名的Session.load()
方法而不是Session.get()
方法。如果域尚未加载到会话中,Session.load()
将只返回域的单元化实体代理(就像您已经加载了一些与域的延迟关联的实体一样),而不会访问数据库。
也就是说,如果域名不可更改,为什么要在域名字段中设置@Cascade(CascadeType.ALL)
?这意味着每次合并或更新用户时,域名也将被合并或更新。更糟糕的是:如果删除用户,域名也将被删除(如果其他用户引用同一个域,这当然会导致异常)。
答案 1 :(得分:1)
是。要保存像User
这样的子实体,您需要在其中设置父实体,即Domain
实体。
另一种方法是在父实体中定义双向映射(OneToMany),即。域,加载Domain
,在User
中添加一个或多个Domain
对象并仅保存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