我有一个类(Material),它与其他类有三个OneToMany关系。将它们保存到数据库中是没有问题的,并且这种关系有效。从数据库中获取材料也可以正常工作。但我一直在努力正确地更新数据库中的数据。作为参考,我正在使用JPA,Hibernate,Spring Boot和PostgreSQL。我的设置是这样的:
材料实体:
@Entity
@Table(name= "MATERIAL")
public class Material {
@Id
@SequenceGenerator(name = "materialGen", sequenceName = "material_seq", allocationSize = 1)
@GeneratedValue(generator = "materialGen")
@Column(name = "id")
private long id;
@Column(name = "name")
private String name;
@OneToMany(mappedBy = "mat_id", cascade = CascadeType.PERSIST)
private List<AltNames> mat_alt_names;
其中一个关系:(我在示例中只包括一个)
@Entity
@Table(name= "MAT_ALT_NAMES")
public class AltNames{
@Id
@SequenceGenerator(name = "altGen", sequenceName = "alt_seq", allocationSize = 1)
@GeneratedValue(generator = "altGen")
@Column(name = "id")
private long id;
@JsonIgnore
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "mat_id", nullable = false)
private Material mat_id;
@Column(name = "name")
private String name;
其余控制器:
@RequestMapping(value = "editmaterial/{mat_id}", method = RequestMethod.POST, consumes = "application/json")
public ResponseEntity<?> postEditMaterial(@PathVariable("mat_id") String id, @RequestBody Material material){
Material returnMaterial = materialService.editMaterial(Long.valueOf(id), material);
return new ResponseEntity<Object>(returnMaterial, HttpStatus.OK);
}
具有相关方法的服务类:
@Service
@Transactional
public class MaterialService {
@Transactional(propagation = Propagation.REQUIRED)
public Material editMat
erial(long id, Material material) {
EntityManager nem = createEntityManager();
Material oldMaterial = nem.find(Material.class, id);
//Checks if the material is found
if (oldMaterial == null) {
log.error("No materials found by id");
}
nem.getTransaction().begin();
oldMaterial.setName(material.getName());
oldMaterial.setAvg_price(material.getAvg_price());
for (Location l : material.getMat_location()) {
l.setMat_id(material);
}
for (AltNames a : material.getMat_alt_names()) {
a.setMat_id(material);
}
for (Price p : material.getMat_price()) {
p.setMat_id(material);
}
oldMaterial.setMat_alt_names(material.getMat_alt_names());
oldMaterial.setMat_location(material.getMat_location());
oldMaterial.setMat_price(material.getMat_price());
nem.flush();
nem.getTransaction().commit();
nem.close();
return getMaterialByName(material.getName());
}
@Transactional
public EntityManager createEntityManager(){
EntityManagerFactory emf = Persistence.createEntityManagerFactory("default");
EntityManager newEm = emf.createEntityManager();
return newEm;
}
根据任何反馈,我会更新帖子以提供更多相关信息并删除不相关的代码。我现在的问题是这段代码确实更新了数据,但也创建了一个副本。我已经尝试了其他几种方法,包括合并,不使用getTransaction,不使用commit而是使用merge。它要么不更新数据,要么错过oneToMany关系中的数据,要么创建副本。 作为替代方案,我不介意创建副本并删除原件,但我还不知道如何在不产生冲突的情况下删除原件。 任何反馈都将不胜感激,谢谢你的时间。