我有以下结构:表格“parent”和“children”,由parents.id = children.parent_id
绑定。应用程序将这些表中的数据读入以下类的对象:
public class Parent {
private int id;
private Map<String, String> children;
....
}
然后应用程序更改其中的数据。 我需要做的是对现有记录应用更改。我不允许更改父类或数据库结构。我试图通过以下方式使用jpa存储库来做到这一点:
我的实体
@Repository
public interface ParentsDao extends JpaRepository<ParentEntity, Integer> {
}
@Entity
@Table(name = "parents")
public class ParentEntity {
@Id
@GeneratedValue
@Column(name = "id", updatable = false, insertable = false)
private Integer id;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
@JoinColumn(name="parent_id")
private Set<ChildEntity> children;
...
}
@Entity
@Table(name = "children")
public class ChildEntity {
@Id
@GeneratedValue
@Column(name = "id", updatable = false, insertable = false)
private Integer id;
@ManyToOne
@JoinColumn(name="parent_id", updatable = false)
private ScheduledReportsEntity scheduledReport;
@Column(name = "child_name")
private String name;
@Column(name = "child_value")
private String value;
...
}
以下是我的服务,其中action()启动整个事情:将Parent转换为ParentEntity并保存它
public class ParentServiceImpl {
@Autowired
ParentsDao parentsDao;
public
void action(Parent parent) {
ParentEntity entity = convert(parent); // moving data from Parent to ParentEntity object
parentsDao.save(entity); //here I receive exception
}
private ParentEntity convert(Parent parent) {
Set<ChildEntity> children = new HashSet<ChildEntity>();
for(Map.Entry<String, String> entry : simpleObj.getChildren().entrySet()){
ChildEntity childEntity = new ChildEntity();
childEntity.setName(entry.getKey());
childEntity.setValue(entry.getValue());
children.add(entity);
}
ParentEntity entity = new ParentEntity();
entity.setId(parent.getId());
entity.setChildren(children);
return entity;
}
}
但我收到以下错误:
com.app.impl.ParentServiceImpl: org.springframework.dao.DataIntegrityViolationException:
could not insert: [com.app.entities.ChildEntity];
SQL [insert into scheduled_report_params (child_name, child_value, parent_id) values (?, ?, ?)];
constraint [null];
nested exception is org.hibernate.exception.ConstraintViolationException: could not insert: [com.app.entities.ChildEntity]
我有两个问题: 我认为这与儿童缺失的ids有关,对吗? 2.如果原因是缺少ids,那么有什么方法可以以某种方式解决它并提供其他领域的保存? 任何建议都会很棒。 感谢
答案 0 :(得分:1)
您遇到了设计问题。
你是对的,如果id
是子实体的主键,那么它必须存在于来自子集的所有预先存在的(不是新的)ChildEntity
元素中{{1} }元素,如果你修改它。如果没有,Hibernate将尝试插入它们。
所以你必须在两种解决方案中做出选择:
在ParentEntity
中使用生成的主键,并找到将其保留在应用程序中的方法。例如,您可以使用ChildEntity
作为真实的模型类,其中ParentEntity
是视图:
Parent
使用子名作为主键。 class Parent {
private ParentEntity inner;
public Parent(ParentEntity entity) {
inner = entity;
// initialize children or have getChildren to dynamically create it
// from inner.childre
...
}
...
}
看起来像是:
ChildEntity
但是你不能简单地忘记应用程序中的主键。