Java 在插入子对象时休眠插入重复的父对象

Java 在插入子对象时休眠插入重复的父对象,java,spring,hibernate,Java,Spring,Hibernate,我的数据库中已经存在一个父记录。我正在尝试添加一个子项并将其与此父项关联。他们同班。当我尝试添加子实体时,它会重新生成父实体。似乎Hibernate错误地认为我要做一个新的父母了。它是一个Hibernate标记,或者可能是通过值而不是引用传递的东西 实体定义 @Id @GeneratedValue(generator="entitySequence", strategy=GenerationType.AUTO) @SequenceGenerator(name="entitySequence",

我的数据库中已经存在一个父记录。我正在尝试添加一个子项并将其与此父项关联。他们同班。当我尝试添加子实体时,它会重新生成父实体。似乎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;
}

非常感谢您的帮助!谢谢大家!

您使用的是双向关联,因此除了将父对象设置为子对象外,还必须将子对象添加到父对象,即
parent.getChildEntities().add
。更清楚地说:

@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;
}

从我的父实体中删除CascadeType.PERSIST修复了此问题


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

谢谢您的回复。我加了这一行。我收到的第一个错误是关于fetchType懒惰的抱怨。我将两者都改为“渴望”,但它仍在重新插入父对象(以及我在数据库中手动设置的两个孩子(兄弟姐妹?)。这是不准确的。在双向关系中,您只需在拥有方设置关系。看见