java – Spring-Data-Jpa在保持后清除链接实体的所有参数
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java – Spring-Data-Jpa在保持后清除链接实体的所有参数,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3893字,纯文字阅读大概需要6分钟。
内容图文
![java – Spring-Data-Jpa在保持后清除链接实体的所有参数](/upload/InfoBanner/zyjiaocheng/728/d2358594fe0749169dcce9148973470e.jpg)
我正在尝试使用JPA(使用Hibernate)来保存2个实体. Spring数据提供了界面,但我认为这并不重要.
我有一个名为’Model’的主要实体.此模型链接了许多“参数”实体.我正在编写一种方法来保存模型及其参数.
这是方法:
private void cascadeSave(Model model) {
modelRepository.save(model);
for (ParameterValue value : model.getParameterValues()) {
parameterValueRepository.save(value);
}
}
这就是问题:
当我加载之前已经存在的模型时,向它添加一些新参数然后调用此方法来保存它们发生的奇怪事情:
在第一次保存(modelRepository.save)之前,这是调试时模型的数据:
该模型有2个参数,填充值(名称和模型已填充).
现在,在我的方法中保存模型第一次保存后,会发生这种情况.请注意,对象引用是一个不同的,所以Hibernate必须做一些神奇的事情并重新创建值而不是让它们孤立:
由于某种原因,hibernate清除了集合中参数的所有属性.
现在,当在以下代码中保存新参数时,由于非空约束等原因而失败.
我的问题:为什么hibernate会清除所有字段?
以下是相关映射:
的parameterValue
@Entity
@Table(name = "tbl_parameter_value")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "PARAMETER_TYPE")
public abstract class ParameterValue extends AbstractBaseObject {
@Column(nullable = false)
@NotBlank
private String name;
private String stringValue;
private Double doubleValue;
private Integer intValue;
private Boolean booleanValue;
@Enumerated(EnumType.STRING)
private ModelType modelParameterType;
@Column(precision = 7, scale = 6)
private BigDecimal bigDecimalValue;
@Lob
private byte[] blobValue;
ParameterValue() {
}
ParameterValue(String name) {
this.name = name;
}
ModelParameterValue
@Entity
@DiscriminatorValue(value = "MODEL")
public class ModelParameterValue extends ParameterValue {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "model_id", foreignKey = @ForeignKey(name = "FK_VALUE_MODEL"))
private Model model;
ModelParameterValue() {
super();
}
ModelParameterValue(String name) {
super(name);
}
模型
@Entity
@Table(name = "tbl_model")
public class Model extends AbstractBaseObject implements Auditable {
@OneToMany(fetch = FetchType.LAZY, mappedBy = "model")
private Set<ModelParameterValue> parameterValues = new HashSet<>();
编辑
我能用最小的例子重现这一点.
如果你更换所有弹簧数据,这就是幕后发生的事情(em是JPA EntityManager):
public Model simpleTest() {
Model model = new Model("My Test Model");
em.persist(model);
model.addParameter(new Parameter("Param 1"));
em.merge(model);
for (Parameter child : model.getParameters()) {
em.persist(child);
}
return model;
}
执行合并时,参数的所有属性都设置为null.它们实际上只是被全新的参数所取代.
解决方法:
我猜你使用的是Spring Data Jpa作为你的modelRepository.这表明了以下后果.
S save(S entity)
Saves a given entity. Use the returned
instance for further operations as the save operation might have
changed the entity instance completely.
所以这是你遇到的正常行为.
代码应更改为:
model = modelRepository.save(model);
for (ParameterValue value : model.getParameterValues()) {
parameterValueRepository.save(value);
}
编辑:
我认为你的保存功能在意义上是破坏的,你是向后做的.你可以在你的关系中使用CascadeType,或者你必须先保存孩子.
级联
Cascade的工作方式类似于“如果您保存父级,保存子级,如果您更新父级,则更新子级……”
所以我们可以像你那样对你的关系进行级联:
@Entity
@Table(name = "tbl_model")
public class Model extends AbstractBaseObject implements Auditable {
@OneToMany(fetch = FetchType.LAZY, mappedBy = "model", cascade = CascadeType.ALL)
private Set<ModelParameterValue> parameterValues = new HashSet<>();
然后才这样保存
private void cascadeSave(Model model) {
modelRepository.save(model);
//ParamValues will be saved/updated automaticlly if your model has changed
}
自下而上保存
第二种选择只是首先保存params然后用它们建模.
private void cascadeSave(Model model) {
model.setParameterValues(
model.getParameterValues().stream()
.map(param -> parameterValueRepository.save(param))
.collect(Collectors.toSet())
);
modelRepository.save(model);
}
我没有检查我的编译器中的第二个代码,但想法是首先保存子项(ParamValues),将其放入模型然后保存模型:)
内容总结
以上是互联网集市为您收集整理的java – Spring-Data-Jpa在保持后清除链接实体的所有参数全部内容,希望文章能够帮你解决java – Spring-Data-Jpa在保持后清除链接实体的所有参数所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。