在浏览一些hibernate书籍中的代码时,我注意到有关实体类的一些奇怪的事情。 例如,客户有一个地址。给出的映射是
public class Customer implements Serializable {
@Column (name="ID")
@Id
@GeneratedValue (strategy=GenerationType.AUTO)
private Long id;
@OneToOne (cascade=CascadeType.ALL)
@JoinColumn (name="ADDRESS_ID")
private Address address;
...
}
现在,Address类以
的形式给出public class Address implements Serializable{
...
@OneToOne (mappedBy="address")
private Customer customer;
}
这是正确的吗?客户应该是一个地址吗?这看起来很奇怪。当然它使双向关联变得容易。但是,如果我正在建模一个名为Address的类,我不会想象一个Customer字段它(我在OOP方面的知识/经验虽然很小)。
你们有什么想法?..我想知道一些面向对象设计大师的意见..
此致
吉姆
答案 0 :(得分:2)
我同意这有点奇怪。不过,那是为你准备的书籍例子。很难想象你想要从一个地址开始并查询所有拥有该地址的客户的情况。
在现实生活系统中,我倾向于不鼓励将Address作为一个拥有自己的表的独立实体,并倾向于将Address作为一个组件并将其字段包含在Customer中。在大多数情况下,您不会独立于客户管理地址(它们将共享相同的生命周期),并且连接较少且复杂性较少。
答案 1 :(得分:1)
这取决于您是否需要从Address对象访问Customer。我一般不会把它放在那里,但如果它对你的用例有意义,我不会称之为错误。
答案 2 :(得分:1)
这是正确的吗?的是
客户应该是地址吗?的是
对于新手,你的映射说的是,Customer类有一个定义:
private Address address;
此定义是对其相对地址的类级别引用。然后,这将成为hibernate的协议,以查看Customer和Address之间的关系。
Address类中的映射说,我与Customer类有关系,我的引用称为'address',因此当我从Customer类调用时,它应来自该引用。
注意这是班级。然后,Hibernate使用地址的外键将映射转换为表到表映射。
构建新客户时的示例,例如;
Customer customer = new Customer(..);
Address address = new Address(..);
customer.setAddress(address)
dao.save(address);
dao.save(customer);
然后客户将持久存储的主键作为foriegn密钥存储,因此定义;
@JoinColumn (name="ADDRESS_ID")
private Address address;
我认为这是你问题的基本定义。 Read more about Hibernate One-to-One.