Hibernate 如何使用JPA对第三个实体进行约束?
因此,我有一个包含三个实体的模型:文档、模板和源 我的问题的主要来源是,我需要文档的编号对于模板的源是唯一的,但是由于来源是Hibernate 如何使用JPA对第三个实体进行约束?,hibernate,jpa,persistence,Hibernate,Jpa,Persistence,因此,我有一个包含三个实体的模型:文档、模板和源 我的问题的主要来源是,我需要文档的编号对于模板的源是唯一的,但是由于来源是模板的属性(而不是文档),我无法直接为其创建唯一约束 为了澄清,代码中的模型是这样的: @Entity @Table("documents", uniqueConstraints = @UniqueConstraint(columnNames = {"number", "originId"})) public class Document { @Id pr
模板
的属性(而不是文档
),我无法直接为其创建唯一约束
为了澄清,代码中的模型是这样的:
@Entity
@Table("documents",
uniqueConstraints = @UniqueConstraint(columnNames = {"number", "originId"}))
public class Document {
@Id private Long id;
@Column Template template;
@Column Long number;
// ... some other fields
// added extra field to use in the constraint:
@Column Long originId;
@PrePersist
@PreUpdate
private void updateConstraintValue() {
this.originId = getTemplate().getId();
}
}
产地:
@Entity
public class Origin {
@Id private Long id;
// ... some other fields
}
@Entity
public class Template {
@Id private Long id;
@Column private Origin origin;
// ... some other fields
}
@Entity
public class Document {
@Id private Long id;
@Column Template template;
@Column Long number;
// ... some other fields
}
模板:
@Entity
public class Origin {
@Id private Long id;
// ... some other fields
}
@Entity
public class Template {
@Id private Long id;
@Column private Origin origin;
// ... some other fields
}
@Entity
public class Document {
@Id private Long id;
@Column Template template;
@Column Long number;
// ... some other fields
}
文档:
@Entity
public class Origin {
@Id private Long id;
// ... some other fields
}
@Entity
public class Template {
@Id private Long id;
@Column private Origin origin;
// ... some other fields
}
@Entity
public class Document {
@Id private Long id;
@Column Template template;
@Column Long number;
// ... some other fields
}
因此,原点有多个关联的模板,您可以使用模板为原点创建文档
正如我所说的,我的问题的根源是文档的编号对于每个来源都必须是唯一的。
我认为唯一可行的方法是为originId使用一个额外的字段,并尝试保持它的更新
所以,我试着做这样的事情:
@Entity
@Table("documents",
uniqueConstraints = @UniqueConstraint(columnNames = {"number", "originId"}))
public class Document {
@Id private Long id;
@Column Template template;
@Column Long number;
// ... some other fields
// added extra field to use in the constraint:
@Column Long originId;
@PrePersist
@PreUpdate
private void updateConstraintValue() {
this.originId = getTemplate().getId();
}
}
注意:为简洁起见,建议使用getter、setter和其他样板文件
但这并不总是适用于JPA,因为在持久化/更新事件发生时,模板对象不需要是托管实体(只需要为关系设置id即可)
那么我现在想这可能不是最好的方法。所以,我的问题是:
- 我还有其他选择吗?JPA(或Hibernate)API有更好的方法来处理这个问题吗?(顺便说一句,我正在使用JPA2和Hibernate 3.6.10)
- 我是否应该信任客户机代码来传递带有正确id的源对象的模板对象(即使它可能与数据库中的不同)
- 我是否可以更好地在文档中映射源代码本身,并信任客户端代码使其与模板保持同步
@Entity
@Table("documents" )
public class Document {
@Id
@GeneratedValue( strategy = GenerationType.IDENTITY )
private Long id;
@Column Template template;
@Column Long number;
// ... some other fields
}
注意:我已经添加了GeneratedValue注释并删除了源ID对不起,这不可能,这些数字对用户有意义。它们必须是从1开始的序列。事实上,我还有一个专栏,那就是今年,必须对它进行限制,但我省略了,因为我认为它不太相关。在我的真实代码中,我确实为id生成了一个值。这是一个逻辑文档编号,业务规则决定如何分配它。你能举一个文档ID的例子吗?是这样的吗${originId}-${templateId}-${non-uniquesequenceNumber}对!模板实际上并不重要,只是它的来源。它实际上是
${originId}/${year}/${number}
,每年数字都会从1开始。而且,数字必须为空,因为只有在文档签名后才能手动分配。好的,我想我明白你的意思了。在这种情况下,我认为您创建的对象模型可能不是最合适的。如果是我,我会消除这种等级制度。正如您所描述的,“文档有来源”和“文档是从模板创建的”。这告诉我文档对象应该与源和模板有直接关系。通过在文档对象中直接包含originId,您已经走上了这条道路。因此,删除originId,只将Origin本身作为@manytone成员包含在文档中。