我有一个Spring Boot App,其中Hibernate作为JPA提供程序和模型映射器依赖项。场景很简单,我有以下控制器:
@RequestMapping(value = "/contracts", method = RequestMethod.PUT, headers = "Accept=application/json")
@ResponseBody
@Transactional
public ResponseEntity<?> updateContract(@DTO(ContractUpdateDto.class) Contract contract,
UriComponentsBuilder uriComponentsBuilder, final HttpServletRequest request) {
if(contract!=null) {
contract.getWork().setState(contract.getState()); //Problematic code that causes the exception
contractService.updateContract(contract);
return new ResponseEntity<>(HttpStatus.OK);
}
else {
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
}
我拥有的映射如下:
工作
@Entity
@Table(name="work")
@Getter
@Setter
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id")
public class Work implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy= GenerationType.AUTO, generator="native")
@GenericGenerator(name = "native", strategy = "native")
@Column(name="id_work")
private int id;
Some preoperties.....
@OneToOne(mappedBy = "work", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
private Contract contract;
}
合同
@Entity
@Table(name="contract")
@Getter
@Setter
public class Contract {
@Id
@GeneratedValue(strategy= GenerationType.AUTO, generator="native")
@GenericGenerator(name = "native", strategy = "native")
@Column(name="id_contract")
private int id;
Some properties.....
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "fk_contract$milestone", nullable=false)
private Set<Milestone> milestones;
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
@JoinColumn(name="fk_work$contract")
private Work work;
}
里程碑
@Entity
@Table(name="milestone")
@Getter
@Setter
public class Milestone {
@Id
@GeneratedValue(strategy= GenerationType.AUTO, generator="native")
@GenericGenerator(name = "native", strategy = "native")
@Column(name="id_milestone")
private int id;
Some properties...
@OneToOne(cascade = CascadeType.MERGE,fetch = FetchType.EAGER)
@JoinColumn(name="fk_item$milestone")
private Item item;
}
项目
@Entity
@Table(name="item")
@Getter
@Setter
public class Item {
@Id
@GeneratedValue(strategy= GenerationType.AUTO, generator="native")
@GenericGenerator(name = "native", strategy = "native")
@Column(name="id_item")
private int id;
Some properties...
}
DTO:
@Getter
public class ContractUpdateDto {
@Id
private int id;
private String clarifications;
private State state;
private double subtotal;
private double administrationFee;
private Double totalValue;
private Set<MilestoneUpdateDto> milestones;
}
@Getter
public class MilestoneUpdateDto {
@Id
private int id;
private State state;
private ItemUpdateDto item;
}
@Getter
public class ItemUpdateDto {
@Id
private int id;
private String name;
private double value;
private double durationValue;
private String durationTime;
private double warrantyValue;
private String warrantyTime;
private String workDescription;
private String warrantyDescription;
private String imageContract;
private String commentContract;
}
当我发送一个包含带有里程碑列表的合同的JSON对象时,就会出现问题,其中每个里程碑都有一个Item对象。像这样:
{"id":16,
"contractNumber":"TEIXSK",
"creationDate":1534772800000,
"state":"CONTRACT_MODIFIED_BY_PROVIDER",
"subtotal":211221,
"administrationFee":10561,
"totalValue":221782,
"milestones":[{"id":15,"state":"CREATED",
"item":{
"id":8,
"name":"Nueva Prueba",
"value":211221,
"durationValue":2,
"durationTime":"Mes(es)",
"warrantyValue":2,
"warrantyTime":"Año(s)",
"workDescription":"sads",
"warrantyDescription":"sdsad",
"imageContract":"data:image/jpeg;base64",
"commentContract":"añadido"}}],
"clarifications":"añadido"
}
发送上述对象后,出现以下错误:
java.lang.IllegalStateException:相同的多个表示形式 实体[com.espiritware.opusclick.model.Item#8]正在合并。 分离:[com.espiritware.opusclick.model.Item@530a9998];分离: [com.espiritware.opusclick.model.Item@78eae981]在 org.hibernate.event.internal.EntityCopyNotAllowedObserver.entityCopyDetected(EntityCopyNotAllowedObserver.java:37) 〜[hibernate-core-5.0.12.Final.jar:5.0.12.Final]在 org.hibernate.event.internal.MergeContext.put(MergeContext.java:256) 〜[hibernate-core-5.0.12.Final.jar:5.0.12.Final]在 org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:304) 〜[hibernate-core-5.0.12.Final.jar:5.0.12.Final]在 org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:170) 〜[hibernate-core-5.0.12.Final.jar:5.0.12.Final]在 org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:850) 〜[hibernate-core-5.0.12.Final.jar:5.0.12.Final]在 org.hibernate.internal.SessionImpl.merge(SessionImpl.java:832) 〜[hibernate-core-5.0.12.Final.jar:5.0.12.Final]在 org.hibernate.engine.spi.CascadingActions $ 6.cascade(CascadingActions.java:260) 〜[hibernate-core-5.0.12.Final.jar:5.0.12.Final]在 org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:398) 〜[hibernate-core-5.0.12.Final.jar:5.0.12.Final]在 org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:323) 〜[hibernate-core-5.0.12.Final.jar:5.0.12.Final]在 org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:162) 〜[hibernate-core-5.0.12.Final.jar:5.0.12.Final]在 org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:431) 〜[hibernate-core-5.0.12.Final.jar:5.0.12.Final]在 org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:363) 〜[hibernate-core-5.0.12.Final.jar:5.0.12.Final]在 org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:326) 〜[hibernate-core-5.0.12.Final.jar:5.0.12.Final]在 org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:162) 〜[hibernate-core-5.0.12.Final.jar:5.0.12.Final]在 org.hibernate.engine.internal.Cascade.cascade(Cascade.java:111) 〜[hibernate-core-5.0.12.Final.jar:5.0.12.Final]在 org.hibernate.event.internal.DefaultMergeEventListener.cascadeOnMerge(DefaultMergeEventListener.java:468) 〜[hibernate-core-5.0.12.Final.jar:5.0.12.Final] at
我的问题是为什么会发生这种情况,在这种情况下此异常指的是..因为如果我在控制器中注释了这一行:
contract.getWork().setState(contract.getState());
问题消失了,一切正常。...我的问题是,为什么在评论时会出现这种现象 非常感谢您的宝贵时间!