Hibernate中的三元(和n-ary)关系
问1)我们如何使用Hibernate建模三元关系? 例如,我们如何使用Hibernate(或JPA)对这里呈现的三元关系进行建模?
注意 :我知道JPA 2添加了一些用于使用地图构建三元关系的构造。 但是,这个问题假设JPA 1或Hibernate 3.3.x并且我不喜欢使用map来对此进行建模。
ER模型http://sofzh.miximages.com/java/image043.gif
替代三元关系的ER模型http://sofzh.miximages.com/java/image045.gif
理想情况下,我更喜欢我的模型:
class SaleAssistant { Long id; //... } class Customer { Long id; //... } class Product { Long id; //... } class Sale { SalesAssistant soldBy; Customer buyer; Product product; //... }
问1.1)
我们如何对这种变化进行建模,其中每个Sale项目可能包含许多产品?
class SaleAssistant { Long id; //... } class Customer { Long id; //... } class Product { Long id; //... } class Sale { SalesAssistant soldBy; Customer buyer; Set products; //... }
问2)一般来说,我们如何用Hibernate建模n-ary,n> = 3的关系?
提前致谢。
Q1。 我们如何使用Hibernate建模三元关系? 例如,我们如何使用Hibernate(或JPA)对这里呈现的三元关系进行建模? (……)
我会改造与中间实体类的关联(这是Hibernate的推荐方法)。 适用于您的示例:
@Entity public class Sale { @Embeddable public static class Pk implements Serializable { @Column(nullable = false, updatable = false) private Long soldById; @Column(nullable = false, updatable = false) private Long buyerId; @Column(nullable = false, updatable = false) private Long productId; public Pk() {} public Pk(Long soldById, Long buyerId, Long productId) { ... } // getters, setters, equals, hashCode } @EmbeddedId private Pk pk; @ManyToOne @JoinColumn(name = "SOLDBYID", insertable = false, updatable = false) private SaleAssistant soldBy; @ManyToOne @JoinColumn(name = "BUYERID", insertable = false, updatable = false) private Customer buyer; @ManyToOne @JoinColumn(name = "PRODUCTID", insertable = false, updatable = false) private Product product; // getters, setters, equals, hashCode }
Q1.1。 我们如何对这种变化进行建模,其中每个Sale项目可能包含许多产品?
我不会在这里使用复合主键并为Sale
实体引入PK。
Q2。 一般来说,我们如何用Hibernate建模n-ary,n> = 3的关系?
我认为我对Q1的回答。 涵盖了这个。 如果没有,请澄清。
更新:回答OP的评论
(…)pk的字段没有填充,因此我无法在DB中保存Sale项目。 我应该在Sale类中使用这样的setter吗? public void setBuyer(Customer cust){this.buyer = cust; this.pk.buyerId = cust.getId(); }
您需要创建一个新的Pk
(我从原始答案中删除了构造函数以获得简洁性)并将其设置在Sale
项目上。 我会做这样的事情:
Sale sale = new Sale(); Pk pk = new Pk(saleAssistant.getId(), customer.getId(), product.getId()); sale.setPk(pk); sale.setSoldBy(saleAssistant); sale.setBuyer(customer); sale.setProduct(product); ...
然后坚持sale
。
另外,在JoinColumn注释中,哪个列是“name”字段引用? 目标关系’pks或销售表自己的列名?
对于复合Pk
属性的列(即销售表自己的列名),我们希望它们获得PK 和FK约束。
您是否为Customer,Product和SalesAssistant使用数据库生成的主键? 这可能会导致问题,因为看起来您正在尝试使用实际的数据库身份,而不是让Hibernate在实际持久性期间解析对象引用。
以上嵌入式PK对我个人来说很奇怪,但我没有机会尝试一下。 看起来这些列是重叠的,彼此相互冲突。
我认为只需拥有ManyToOne参考就足够了。
此外,打开SQL语句调试并查看发送到数据库的内容。
- 可以在@ManyToMany Hibernate额外表中添加额外的字段吗?
- 如何解决“org.hibernate.QueryException:并未设置所有命名参数”错误?
- Hibernate – 它改变了数据库的结构吗?
- 使用Oracle 10g时,Hibernate对浮点列的模式validation的已知问题有哪些最佳解决方法?
- Hibernate持久化Map 而不引用另一个表
- org.codehaus.jackson.map.JsonMappingException:无限递归(StackOverflowError)
- Hibernate和NonUniqueObjectException
- 期望在模型属性@RequestBody或@RequestPart参数之后立即声明Errors / BindingResult参数
- hibernate:从列表中删除项目不会保留