我有一个关于保存相关实体的大问题。我需要保存多个elementaryflowbase对象:
@Data
@Entity
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class ElementaryFlowBase {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@EqualsAndHashCode.Include
private UUID id;
private String name;
@ManyToOne
@JoinColumn(name = "fk_elementary_flow_category", referencedColumnName = "id")
private ElementaryFlowCategory category;
@ManyToOne
@JoinColumn(name = "fk_elementary_flow_sub_category", referencedColumnName = "id")
private ElementaryFlowSubCategory subCategory;
@ManyToOne
@JoinColumn(name = "fk_source_info", referencedColumnName = "id")
private SourceInfo sourceInfo;
@ManyToOne
@JoinColumn(name = "fk_uom", referencedColumnName = "id")
private UnitOfMeasure unitOfMeasure;
@OneToMany(mappedBy = "elementaryFlowBase", cascade = CascadeType.PERSIST)
private Set<BaseEnvironmentalImpact> coefficientFactors;
@EqualsAndHashCode.Include
private String originalId;
}
在它里面有不同的baseenvironmentalimpact(我使用cascade将它们从父母那里解救出来)。
@Data
@Entity
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class BaseEnvironmentalImpact {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@EqualsAndHashCode.Include
private UUID id;
private double value;
private double normalizedValue;
@ManyToOne(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
@JoinColumn(name = "fk_methodology", referencedColumnName = "id")
private Methodology methodology;
@ManyToOne(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
@JoinColumn(name = "fk_impact_category", referencedColumnName = "id")
private ImpactCategory impactCategory;
@ManyToOne(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
@JoinColumn(name = "fk_impact_indicator", referencedColumnName = "id")
private ImpactIndicator impactIndicator;
@ManyToOne
@JoinColumn(name = "fk_source_info", referencedColumnName = "id")
private SourceInfo sourceInfo;
@EqualsAndHashCode.Include
private String originalId;
//ref
@ManyToOne
@JoinColumn(name = "fk_elementary_flow_base")
private ElementaryFlowBase elementaryFlowBase;
@ManyToOne
@JoinColumns({
@JoinColumn(
name = "process_base_id",
referencedColumnName = "process_base_id"),
@JoinColumn(
name = "reference_product_id",
referencedColumnName = "reference_product_id")
})
private ProcessTemplate processTemplate;
}
基本环境影响有方法论、影响类别、影响指标(这些实体也是相关的)。
方法:
@Data
@Entity
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class Methodology {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@EqualsAndHashCode.Include
private UUID id;
private String name;
@OneToMany(mappedBy = "methodology", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<ImpactCategory> impactCategories;
@ManyToOne
@JoinColumn(name = "fk_source_info", referencedColumnName = "id")
private SourceInfo sourceInfo;
@EqualsAndHashCode.Include
private String originalId;
}
影响类别:
@Data
@Entity
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class ImpactCategory {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@EqualsAndHashCode.Include
private UUID id;
private String name;
@OneToMany(mappedBy = "impactCategory", cascade = CascadeType.PERSIST)
private Set<ImpactIndicator> impactIndicators;
//ref
@ManyToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name = "fk_methodology", referencedColumnName = "id")
private Methodology methodology;
@ManyToOne
@JoinColumn(name = "fk_source_info", referencedColumnName = "id")
private SourceInfo sourceInfo;
@EqualsAndHashCode.Include
private String originalId;
}
碰撞指示器:
@Data
@Entity
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class ImpactIndicator {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@EqualsAndHashCode.Include
private UUID id;
private String name;
@ManyToOne
@JoinColumn(name = "fk_uom", referencedColumnName = "id")
private UnitOfMeasure unitOfMeasure;
//ref
@ManyToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name= "fk_impact_category", referencedColumnName = "id")
private ImpactCategory impactCategory;
@ManyToOne
@JoinColumn(name = "fk_source_info", referencedColumnName = "id")
private SourceInfo sourceInfo;
@EqualsAndHashCode.Include
private String originalId;
}
保存elementaryflowbase我想使用级联保存所有这些实体。
通过这些设置,我可以保存第一个元素FlowBase(使用Crudepository):
@GetMapping("/elementaryflowbases")
public String importElementaryFlowBases() {
System.out.println("Elementary flow bases import started");
Set<ElementaryFlowBase> items = importer.getElementaryFlowBases();
for (ElementaryFlowBase item : items){
elementaryFlowBaseRepository.save(item);
}
return "Elementary flow bases has been imported: + " + items.size() + "elements!";
}
但是在第二步,我有一个错误:
detached entity passed to persist: xxx.sp_model.sustainability.model.assessment.ImpactCategory
方法、影响类别、影响指标可能与某些基本环境影响相同。但是一些基本的环境影响可能有其他的方法,影响类别,影响指标。所以对于cascade,我想保存或更新(或者使用db上的内容,对我来说是一样的)。
怎么了?有什么建议吗?
先谢谢你
编辑saveall(不带for循环)解决问题。但这是一个测试,看看如何保存或更新数据库中已经存在的东西。为了更好地理解,我有另一个对象,称为processtemplate,它有其他baseenvironmentalimpact,但可以使用相同的方法、impactcategory和impactindicator:
@Data
@Entity
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class ProcessTemplate {
@EmbeddedId
@EqualsAndHashCode.Include
private ProcessTemplateId id;
@ManyToOne
@JoinColumn(name = "fk_process_base", referencedColumnName = "id")
private ProcessBase processBase;
@ManyToOne
@JoinColumn(name = "fk_reference_flow_base", referencedColumnName = "id")
private FlowBase referenceProduct;
@ManyToMany(cascade = CascadeType.MERGE)
@JoinTable(
name="processtemplates_flowtemplates",
joinColumns={
@JoinColumn(name = "process_base_id", referencedColumnName = "process_base_id"),
@JoinColumn(name = "reference_product_id", referencedColumnName = "reference_product_id")
},
inverseJoinColumns = @JoinColumn(name = "fk_flowtemplate", referencedColumnName = "id")
)
private Set<FlowTemplate> flowsTemplate;
@OneToMany(cascade = CascadeType.MERGE)
private Set<ElementaryFlowTemplate> elementaryFlowsTemplate;
@ManyToOne
@JoinColumn(name = "fk_source_info", referencedColumnName = "id")
private SourceInfo sourceInfo;
@Enumerated(EnumType.STRING)
private Validation validation;
@OneToMany(cascade = CascadeType.MERGE)
private Set<BaseEnvironmentalImpact> environmentalImpacts;
@EqualsAndHashCode.Include
private String originalId;
@PrePersist
void id() {
this.id = new ProcessTemplateId(processBase.getId(), referenceProduct.getId());
}
}
saveall解决了前面的问题,但这里我又遇到了同样的问题。所以这个建议似乎使用了事务性的。我可以这样用吗,因为我用的是粗积存法?
@Transactional
@GetMapping("/run")
public String run() {
if(importer.runImporter() == 0){
...
System.out.println(importElementaryFlowBases());
System.out.println(importProcessTemplates());
return "Import process has been executed";
}
else{
return "Fail on import";
}
}
public String importElementaryFlowBases() {
System.out.println("Elementary flow bases import started");
Set<ElementaryFlowBase> items = importer.getElementaryFlowBases();
elementaryFlowBaseRepository.saveAll(items);
return "Elementary flow bases has been imported: + " + items.size() + "elements!";
}
public String importProcessTemplates() {
System.out.println("Process templates import started");
Set<ProcessTemplate> items = importer.getProcessTemplates();
processTemplateRepository.saveAll(items);
return "Process templates has been imported: + " + items.size() + "elements!";
}
暂无答案!
目前还没有任何答案,快来回答吧!