嵌套实体在保存后包含 null
Nested entities contains null after save
我有一个实体,其中包含一些像这样的嵌套实体
public class MyEntity {
@ManyToOne
@JoinColumn(name="FK_ENTITY2")
private Entity2 fkEntity2;
@ManyToOne
@JoinColumn(name="FK_ENTITY3")
private Entity3 fkEntity3;
}
实体 2 和实体 3 像这样:
public class Entity2/3{
@Id
private Long id;
@Column(name = "code")
private String code;
@Column(name = "desc")
private String desc;
//getter and setter etc
}
Entity2
和 Entity3
都在数据库中存储了值,所以当我在 MyEntity
上插入时,我这样做:
@Transactional
@Service
public MyService {
//idFromController and otherIdFromController refers to existent records in the database
public MyDto save(Long idFromController, Long otherIdFromController){
Entity2 entity2 = new Entity2();
entity2.setId(idFromController);
Entity3 entity3 = new Entity3();
entity3.setId(otherIdFromController);
MyEntity newMyEntity = new MyEntity();
newMyEntity.setEntity2(entity2);
newMyEntity.setEntity3(entity3);
MyEntity result = myEntityRepository.saveAndFlush(newMyEntity);
return getDto(result);
}
}
工作正常,数据使用正确的外键正确存储在数据库中,但是...
插入后我想构建一个包含嵌套实体的 id、代码和 desc 的 DTO,如下所示:
private MyDto getDto(MyEntity result){
MyDto dto = new MyDto();
dto.setId2(result.getEntity2().getId());
dto.setCode2(result.getEntity2().getCode());
dto.setDesc2(result.getEntity2().getDesc());
dto.setId3(result.getEntity3().getId());
dto.setCode3(result.getEntity3().getCode());
dto.setDesc3(result.getEntity3().getDesc());
}
这是问题所在,我在代码和描述中只得到了 id 字段和 null。
当我在搜索中调用 getDto()
时它起作用并且每个字段都有正确的值,所以它与插入事务有关?我该如何解决这个问题?
当您创建 DTO 时,(现有的)实体没有附加到持久化上下文,因此相应的数据还没有从数据库中加载,无法复制到 DTO。
一个选项是加载实体,例如通过 'myRepository.findById...' 并关联返回的(托管)实体。
您错过了多对一关系的某些部分。首先在 MyEntity
class 中最好定义一个获取类型。在 Entity2
和 Entity3
中,您需要将 @OneToMany
定义为与获取类型声明的关系的另一端,而 cascade = CascadeType.ALL
只是告诉休眠它可以用相对的方式做什么进行保存、删除、更新时的实体。我将您的代码重新格式化如下
public class Entity2/3{
@Id
private Long id;
@Column(name = "code")
private String code;
@Column(name = "desc")
private String desc;
@OneToMany(cascade = CascadeType.ALL,mappedBy ="fkEntity2",fetch=FetchType.LAZY)
private List<Entity2> entityTwoList;
// for Entity3
@OneToMany(cascade = CascadeType.ALL,mappedBy ="fkEntity3",fetch=FetchType.LAZY)
private List<Entity3> entityThreeList;
public class MyEntity {
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="FK_ENTITY2")
private Entity2 fkEntity2;
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="FK_ENTITY3")
private Entity3 fkEntity3;
}
}
我有一个实体,其中包含一些像这样的嵌套实体
public class MyEntity {
@ManyToOne
@JoinColumn(name="FK_ENTITY2")
private Entity2 fkEntity2;
@ManyToOne
@JoinColumn(name="FK_ENTITY3")
private Entity3 fkEntity3;
}
实体 2 和实体 3 像这样:
public class Entity2/3{
@Id
private Long id;
@Column(name = "code")
private String code;
@Column(name = "desc")
private String desc;
//getter and setter etc
}
Entity2
和 Entity3
都在数据库中存储了值,所以当我在 MyEntity
上插入时,我这样做:
@Transactional
@Service
public MyService {
//idFromController and otherIdFromController refers to existent records in the database
public MyDto save(Long idFromController, Long otherIdFromController){
Entity2 entity2 = new Entity2();
entity2.setId(idFromController);
Entity3 entity3 = new Entity3();
entity3.setId(otherIdFromController);
MyEntity newMyEntity = new MyEntity();
newMyEntity.setEntity2(entity2);
newMyEntity.setEntity3(entity3);
MyEntity result = myEntityRepository.saveAndFlush(newMyEntity);
return getDto(result);
}
}
工作正常,数据使用正确的外键正确存储在数据库中,但是... 插入后我想构建一个包含嵌套实体的 id、代码和 desc 的 DTO,如下所示:
private MyDto getDto(MyEntity result){
MyDto dto = new MyDto();
dto.setId2(result.getEntity2().getId());
dto.setCode2(result.getEntity2().getCode());
dto.setDesc2(result.getEntity2().getDesc());
dto.setId3(result.getEntity3().getId());
dto.setCode3(result.getEntity3().getCode());
dto.setDesc3(result.getEntity3().getDesc());
}
这是问题所在,我在代码和描述中只得到了 id 字段和 null。
当我在搜索中调用 getDto()
时它起作用并且每个字段都有正确的值,所以它与插入事务有关?我该如何解决这个问题?
当您创建 DTO 时,(现有的)实体没有附加到持久化上下文,因此相应的数据还没有从数据库中加载,无法复制到 DTO。
一个选项是加载实体,例如通过 'myRepository.findById...' 并关联返回的(托管)实体。
您错过了多对一关系的某些部分。首先在 MyEntity
class 中最好定义一个获取类型。在 Entity2
和 Entity3
中,您需要将 @OneToMany
定义为与获取类型声明的关系的另一端,而 cascade = CascadeType.ALL
只是告诉休眠它可以用相对的方式做什么进行保存、删除、更新时的实体。我将您的代码重新格式化如下
public class Entity2/3{
@Id
private Long id;
@Column(name = "code")
private String code;
@Column(name = "desc")
private String desc;
@OneToMany(cascade = CascadeType.ALL,mappedBy ="fkEntity2",fetch=FetchType.LAZY)
private List<Entity2> entityTwoList;
// for Entity3
@OneToMany(cascade = CascadeType.ALL,mappedBy ="fkEntity3",fetch=FetchType.LAZY)
private List<Entity3> entityThreeList;
public class MyEntity {
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="FK_ENTITY2")
private Entity2 fkEntity2;
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="FK_ENTITY3")
private Entity3 fkEntity3;
}
}