我已经实现了方法 AttributeConverter.convertToEntityAttribute ,以便从数据库加载json数据。我不是要保留数据,但是由于某些原因,正在调用 convertToDatabaseColumn 。
这就是发生的情况:
1.我调用存储库方法
2.然后调用AttributeConverter.convertToEntityAttribute->返回实体Cx的列表。至此一切正常。
3.但是由于某种原因,之后立即调用AttributeConverter.convertToDatabaseColumn,使用相同的实体Cx 列表作为参数->返回 stringV
4.现在再次以 stringV 作为参数再次调用convertToEntityAttribute,这也很奇怪。
可能是@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时会发生这种情况
答案 0 :(得分:1)
是的,它的行为确实像您说的那样。同样,在保留RST时,Converter也称为3x。
在仅读取RS实体时也称为3x,即不是由@OneToOne关系引起的。
我认为这就是休眠的方式。没问题,您可以正确地获取正确的数据。
从stacktrace中,我看到第二个和第三个调用来自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
找到了更多相关信息另一件事:仅当在集合上使用转换器时,才会发生这种情况。如果Converter用于单一类型(例如AttributeConverter<String, String>
),则会调用一次。