java - 当数据没有被持久化时,convertToDatabaseColumn?
问题描述
我已经实现了方法AttributeConverter.convertToEntityAttribute来从数据库加载 json 数据。我不是要保留数据,但由于某种原因正在调用convertToDatabaseColumn 。
这是发生的情况:
1. 我调用存储库方法
2. 然后调用 AttributeConverter.convertToEntityAttribute -> 返回实体 Cx 的列表。至此一切正常。
3. 但是由于某种原因 AttributeConverter.convertToDatabaseColumn 被立即调用,实体 Cx 的相同列表作为参数 -> 返回stringV
4.现在 convertToEntityAttribute 再次以stringV作为参数调用,这也很奇怪。
会不会是 @OneToOne 关系导致了这种情况?如果我没有持久化实体,为什么要执行 convertToDatabaseColumn,至少是明确的?
所有这一切都发生在我的一个存储库类中调用一个方法:
这是代码
public interface RSTRepository extends CrudRepository<RST, Long> {
List<RST> findByDuctNameIgnoreCase(String ductName);
}
@Entity
@Table(name="r_s_t")
public class RST {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
@OneToOne
@JoinColumn(name = "r_s_id")
private Rs rs;
@Column(name = "channel")
private String channelName;
...
}
@Entity
@Table(name="r_s")
public class RS {
@Id
@Column(name = "rs_id", columnDefinition = "json")
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
@Column(name = "c_x", columnDefinition = "json")
@Convert(converter = JsonToCxConverter.class)
private List<Cx> cxs;
...
}
public class Cx {
private Long someId;
private List<Long> values;
...
}
@Converter
public class JsonToCxConverterimplements AttributeConverter<List<Cx>, String>{
//this gets executed
@Override
public String convertToDatabaseColumn(List<Cx> entityAttribute) {
ObjectMapper objectMapper = new ObjectMapper();
log.info("--------------------");
return "";
}
@Override
public List<Cs> convertToEntityAttribute(String dbData) {
if (dbData == null || dbData.isEmpty()) return Collections.emptyList();
//... uses the object mapper to parse the json and return a simple object.
...
}
就像我说的,这发生在调用 RSTRepository.findByDuctNameIgnoreCase
解决方案
是的,它的行为就像你说的那样。同样在坚持 RST 时,Converter 也称为 3x。
仅读取 RS 实体时也称为 3x,即不是由 @OneToOne 关系引起的。
我认为这就是hibernate的工作方式。这应该不是问题,您可以获得正确的数据而不会出错。
从堆栈跟踪我看到第二个和第三个调用来自 AbstractRowReader.performTwoPhaseLoad()。
at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.performTwoPhaseLoad(AbstractRowReader.java:241)
at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.finishUp(AbstractRowReader.java:209)
at org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl.extractResults(ResultSetProcessorImpl.java:133)
我认为它不能被禁用。从休眠来源我看到该实体已注册为“保湿”。我在这里找到了更多关于它的信息https://stackoverflow.com/a/29538797/2044957
另一件事:只有在对集合使用转换器时才会发生这种情况。如果转换器用于单一类型,则调用一次,例如AttributeConverter<String, String>
.
推荐阅读
- javascript - 如何相对于单击的按钮对齐 react-bootstrap 模式
- mysql - 更新 <\DATE> 作为 MSAccess 和 MySQL 保存中字符串的一部分
- typescript - 使用 TypeScript 会使 apk 大小变大?
- css - 如何使css具有每行始终具有相同高度的反应列
- php - 如何通过laravel中的api对Web登录页面进行身份验证
- angular - 为什么 IdentityServer 4 代码流在一段时间后得到 invalid_grant 响应?
- android - android 10中的后台服务每10分钟获取一次位置
- flutter - 颤振将日期时间转换为字符串在午夜失败
- android - Textstyle 在发布时没有唤醒
- string - 如何使用 Flutter TextFormField 在行开头和结尾进行缩进和缩进