如何在不创建重复项的情况下更新与JPA具有oneToMany关系的数据库条目

时间:2016-12-21 12:51:28

标签: java postgresql hibernate jpa spring-boot

我有一个类(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关系中的数据,要么创建副本。 作为替代方案,我不介意创建副本并删除原件,但我还不知道如何在不产生冲突的情况下删除原件。 任何反馈都将不胜感激,谢谢你的时间。

0 个答案:

没有答案