Hibernate在插入子对象时插入重复的父对象

时间:2017-08-11 13:34:28

标签: java spring hibernate

我的数据库中已存在父记录。我正在尝试添加一个孩子并将其与此父母相关联。他们共享同一个班级。当我尝试添加子项时,它会重新创建父实体。似乎Hibernate错误地认为我正在创建一个新的父母。它是一个Hibernate标签还是有些东西通过值传递而不是引用?

实体定义

@Id
@GeneratedValue(generator="entitySequence", strategy=GenerationType.AUTO)
@SequenceGenerator(name="entitySequence", initialValue=1,
sequenceName="entity_sequence", schema="user_portal")
private Long id;

...


@ManyToOne(fetch=FetchType.LAZY, cascade={CascadeType.PERSIST, 
CascadeType.MERGE, CascadeType.REMOVE})
@JoinColumn(name="parent_id", referencedColumnName="id")
@JsonBackReference
private Entity parentEntity;


@OneToMany(mappedBy="parentEntity", fetch=FetchType.LAZY, 
targetEntity=Entity.class, 
cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE})
@JsonManagedReference
private List<Entity> childEntities;

控制器代码

@RequestMapping(
value = "/add",
    method = RequestMethod.POST,
    headers = HTTP_ACCEPT_JSON_HEADER, 
    produces = HTTP_RESPONSE_JSON_HEADER)
public @ResponseBody WebResponse addEntity(@RequestBody Entity s) {
    WebResponse wr = new WebDataResponse();

    try {
        s = EntityService.saveEntity(s);

        if (s != null) {
            handleSuccess(wr, s, 1);
        } else {
            handleSuccess(wr, null, "Error adding Entity.", 0);
        }

    } catch (Exception ex) {
        handleException(wr, ex);
    }

    return wr;
}

服务代码

@Override
@Transactional
public Entity saveEntity(Entity s) {

    String entityNumber = s.getEntityNumber();
    boolean isAddendum = StringUtils.countOccurrencesOf(entityNumber, "-") == 4;


    if(isAddendum) {
Entity parent = getEntityByNumber(entityNumber.substring(0,entityNumber.lastIndexOf("-")));
        if(parent !=null) {
            s.setParentEntity(parent);
        }else {
            return null;
        }
    }

    s.setCreatedBy("admin");
    s.setCreatedDate(new Date());

    s = entityRepository.save(s);

    return s;
}

@Override
@Transactional(readOnly = true)
public Entity getEntityByNumber(String entityNum) {
    Entity s = entityRepository
            .findByEntityNumber(entityNum);

    return s;
}

非常感谢任何帮助!谢谢!

2 个答案:

答案 0 :(得分:1)

从parentEntity中删除CascadeType.PERSIST解决了这个问题。

我还建议不要手动插入测试变量。使用像Postman这样的应用程序进行API测试调用要好得多。这让我对如何解决问题有了更好的了解(我收到了一个错误,而不是这个重复问题)。

答案 1 :(得分:0)

您正在使用双向关联,因此除了将父级设置为子级之外,您还必须将子级添加到父级,即parent.getChildEntities().add(s)。更清楚:

@Override
@Transactional
public Entity saveEntity(Entity s) {

  String entityNumber = s.getEntityNumber();
  boolean isAddendum = StringUtils.countOccurrencesOf(entityNumber, "-") == 4;


  if(isAddendum) {
    Entity parent = getEntityByNumber(entityNumber.substring(0,entityNumber.lastIndexOf("-")));
    if (parent !=null) {
        s.setParentEntity(parent);
        parent.getChildEntities().add(s);
    } else {
        return null;
    }
  }

  s.setCreatedBy("admin");
  s.setCreatedDate(new Date());

  s = entityRepository.save(s);

  return s;
}