Java Hibernate、@ManyToOne inserts和ehCache
我有一个父->子关系,有一个Java Hibernate、@ManyToOne inserts和ehCache,java,hibernate,jpa,ehcache,Java,Hibernate,Jpa,Ehcache,我有一个父->子关系,有一个@ManyToOne/@OneToMany关系 我正在处理对父级的更新,代码大致如下: 找到父母 从中检索(按顺序-ehCache、db或create(如果找不到) 处理更新,如果未找到,则在父级上创建子级 保存到数据库 存储在缓存中 在运行时,我发现出现了以下顺序 第一次更新完成-父级和子级都创建了缓存 第二次更新-从缓存中检索父级,添加新的子级 当第二次更新完成时,子项的id仍然为空。但是,更新成功完成。(根据hibernate日志和数据库进行验证)
@ManyToOne
/@OneToMany
关系
我正在处理对父级的更新,代码大致如下:
- 找到父母
- 从中检索(按顺序-ehCache、db或create(如果找不到)
- 处理更新,如果未找到,则在父级上创建子级
- 保存到数据库
- 存储在缓存中
- 第一次更新完成-父级和子级都创建了缓存
- 第二次更新-从缓存中检索父级,添加新的子级
- 当第二次更新完成时,子项的id仍然为空。但是,更新成功完成。(根据hibernate日志和数据库进行验证)
- 第三次更新-
被抛出,因为第二次更新的子项被再次插入DataIntegrityViolationException
- 正确定义和注释了父子返回引用
- 在初始插入父级之后,我尝试从数据库中重新获取父级,并缓存它,以查看它是否起到了作用——它没有
- 事务边界必须在这里发挥作用,因为这在我的测试中最初并没有失败,而我的测试被标注为
。(刻苦学习的一课)@Transactional
@Entity // Parent
class Fixture {
@OneToMany(cascade=CascadeType.ALL, mappedBy="fixture", fetch=FetchType.EAGER) @Getter @Setter
@MapKey(name="instrumentPriceId")
private Map<String,Instrument> instruments = Maps.newHashMap();
private Instrument addInstrument(Instrument instrument)
{
instruments.put(instrument.getInstrumentPriceId(), instrument);
instrument.setFixture(this);
log.info("Created instrument {}",instrument.getInstrumentPriceId());
return instrument;
}
/**
* Returns an instrument with the matching instrumentId.
* If the instrument does not exist, it is created, appended to the internal collection,
* and then returned.
*
* This method is guaranteed to always return an instrument.
* This method is thread-safe.
*
* @param instrumentId
* @return
*/
public Instrument getInstrument(String instrumentId)
{
if (!instruments.containsKey(instrumentId))
{
addInstrument(new Instrument(instrumentId));
}
return instruments.get(instrumentId);
}
}
@Entity // Child
public class Instrument {
@Column(unique=true)
@Getter @Setter
private String instrumentPriceId;
@ManyToOne(optional=false)
@Getter @Setter @JsonIgnore
private Fixture fixture;
public Instrument(String instrumentPriceId)
{
this.instrumentPriceId = instrumentPriceId;
}
}
}这个问题的答案简单得令人沮丧 在
update
方法中,我忽略了save()
操作的结果。
通常,如果您不打算再次使用对象,这是很好的。(这是很常见的,因为您在工作单元结束时保存了)
但是,当我再次继续使用“父项”时,我需要观察返回值:
因此:
fixtureRepository.save(fixture);
fixtureCache.put(new Element(fixtureId, fixture));
变成这样:
fixture = fixtureRepository.save(fixture);
fixtureCache.put(new Element(fixtureId, fixture));
fixture = fixtureRepository.save(fixture);
fixtureCache.put(new Element(fixtureId, fixture));