Java 在子实体中使用无ID的onetomany连接更新实体
我有以下结构:表“parents”和“children”,它们由parents.id=children.parent\u id绑定 应用程序将这些表中的数据读取到以下类的对象中:Java 在子实体中使用无ID的onetomany连接更新实体,java,spring,hibernate,jpa,Java,Spring,Hibernate,Jpa,我有以下结构:表“parents”和“children”,它们由parents.id=children.parent\u id绑定 应用程序将这些表中的数据读取到以下类的对象中: public class Parent { private int id; private Map<String, String> children; .... } 我有两个问题: 1.我认为这与儿童身份证缺失有关,对吗? 2.如果原因是缺少ID,那么有没有办法绕过它,并通过其他字
public class Parent {
private int id;
private Map<String, String> children;
....
}
我有两个问题:
1.我认为这与儿童身份证缺失有关,对吗?
2.如果原因是缺少ID,那么有没有办法绕过它,并通过其他字段提供save?
非常感谢你的建议。
谢谢您有一个设计问题 您是对的,如果
id
是子实体的主键,那么它必须存在于ParentEntity
元素的子集合中的所有预先存在(不是新的)ChildEntity
元素中(如果您修改它)。如果没有,Hibernate将尝试插入它们
因此,您必须在两种解决方案中进行选择:
- 在
中使用生成的主键,并找到将其保存在应用程序中的方法。例如,您可以使用ChildEntity
作为真实的模型类,其中ParentEntity
是它的一个视图:Parent
- 使用子名称作为主键。
看起来像:ChildEntity
@Entity @Table(name = "children") public class ChildEntity { @Id @Column(name = "child_name") private String name; @Column(name = "child_value") private String value; @ManyToOne @JoinColumn(name="parent_id", updatable = false) private ScheduledReportsEntity scheduledReport; ... }
但是,您不能简单地忘记应用程序中的主键。没有包含ID的子项”是什么意思?如果有一个ChildEntity,那么它有一个id,这就是识别它的方法。不知道与下面代码相关的Map的顶级示例是什么应用程序与包含Map的简单父级一起工作。为了更新,我通过填充所有字段将其转换为ParentEntity。映射被转换为子实体列表,但没有ID,因为父实体根本没有ID。我猜你的回答意味着没有办法通过其他字段然后id来更新子实体。我说的对吗?不知道什么是“更新”。映射有一个字符串键和字符串值(在单独的表中)。您可以像更新任何地图一样更新地图,JPA提供商应该更新地图的表。我的JPA提供商工作正常。只有当某个对象需要自己的表时,才能将其作为一个实体。我需要将子对象映射放在一个单独的表中。是的,它会创建ok新记录,但无法更新现有记录。所以我想这可能是因为孩子们缺少身份证。不确定这是否会澄清一些事情,但我更新了帖子。如果丢失ID不是原因,那么也许你可以建议我去哪里找。感谢您的回答另一个问题-看起来对我来说唯一的方法就是创建父\子\ id和子\名的复合主键。问题是,是否可以同时将父id用作主键的一部分和多通连接的绑定器?也许你可以提供有用的例子链接。。谢谢,这是可能的。您应该看看Hibernate手册,基本O/R映射/标识符-我看到了一个id作为属性的示例,它使用的组件类型可能接近您需要的类型。
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]
class Parent {
private ParentEntity inner;
public Parent(ParentEntity entity) {
inner = entity;
// initialize children or have getChildren to dynamically create it
// from inner.childre
...
}
...
}
@Entity
@Table(name = "children")
public class ChildEntity {
@Id
@Column(name = "child_name")
private String name;
@Column(name = "child_value")
private String value;
@ManyToOne
@JoinColumn(name="parent_id", updatable = false)
private ScheduledReportsEntity scheduledReport;
...
}