让我们从这个实体开始:
@Entity
public class MyEntity {
...
@Column(length = 80)
private String description;
@Column(name = "enum_column", precision = 18)
@Convert(converter = EnumColumnConverter.class)
private MyEnum enumColumn;
...
}
在这里,您会看到两列可为空(在我的实体和数据库中)。转换器将枚举替换为数据库中的 Long
值。相应地定义了存储库类:
@Repository
public interface MyEntityRepository extends JpaRepository<MyEntity, Long> {}
DTO 是从服务包定义的:
public class MyEntityDto {
...
private String description;
private MyEnum enumColumn;
...
}
DTO 和实体之间的映射是使用 Dozer 完成的。 DTO 是从 Java FX UI 修改的。在 UI 和持久性之间定义了一个服务来保存修改的实体。
@Service
@Transactional
public class MyEntityService {
@Autowired MyEntityRepository myEntityRepository;
...
public List<MyEntityDto> save(List<MyEntityDto> dtosToSave) {
List<MyEntityDto> results = Collections.emptyList();
if (dtosToSave != null && !dtosToSave.empty()) {
Iterable<MyEntity> entities = convertDtosWithDozer(dtosToSave);
List<MyEntity> savedEntities = myEntityRepository.saveAll(entities);
results = convertEntitiesWithDozer(savedEntities);
}
return results;
}
在 UI 中,我修改了一个现有行,其中 description
和 enumColumn
都不为 null
。这两个值都设置为 null
。
问题是数据库中它们都没有设置为null
。在日志中,Hibernate 生成的 update
请求不包含这些列。当我调试代码时,dtosToSave
、entities
、savedEntities
和 results< 中的这些列为
.null
/
我为 MyEntityRepository
创建了一个单元测试,其中保存了一个具有非空 description
和 entityColumn
的实体。我使用存储库从数据库重新加载实体,以确保这些列不为空。我将它们设置为 null
,保存实体,然后从数据库加载它。现在两列确实都是 null
,这正是我所期待的。
我的问题:我在这里缺少什么?为什么存储库不保存 null
列?如果我设置任何非空值,它就可以正常工作。
提前致谢。
更新:我的问题可能与此有关吗? Jpa Repository save() doesn't update existing data
最佳答案
您通过推土机将 dtos 转换为实体,但此时实体仍处于分离状态......要更新现有实体,您首先需要通过存储库通过数据库加载它们。类似 repository.findById(Id id);
然后您将获得处于“附加”状态的实体,因此将应用状态转换(字段更新)。
在 save()
期间,您的所有实体状态转换都将转换为相应的 DML,并且您的更新现在应该可以工作。
关于此声明
I reload the entity from the database using the repository to be sure these columns are not null. I set them to null, save the entity, and load it back from the database. Now both columns are indeed null, which is what I've been expecting.
正如你所说你从数据库中重新加载实体
所以它可以工作
关于java - 为什么不能使用 JPA 将列设置为 null?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61253663/