Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Hibernate 如何使用JPA对第三个实体进行约束?_Hibernate_Jpa_Persistence - Fatal编程技术网

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的源对象的模板对象(即使它可能与数据库中的不同)
  • 我是否可以更好地在文档中映射源代码本身,并信任客户端代码使其与模板保持同步

我可能遗漏了一些东西,但您能否完全摆脱原始ID,只需为文档使用生成的ID,而不是手动创建一个ID?您已经在那里有一个ID列。看起来您所需要做的就是指定要生成的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成员包含在文档中。