我有一个抽象类,只提供对会话创建的简单访问:
private Session currentSession = null;
private Transaction currentTransaction = null;
protected void openSession() {
this.currentSession = HibernateSession.openSession();
}
protected void openSessionWithTransaction() {
this.currentSession = HibernateSession.openSession();
this.currentTransaction = this.currentSession.beginTransaction();
}
public void closeSessionWithTransaction() {
this.currentTransaction.commit();
this.currentSession.close();
}
我注意到当我尝试检索条目时
Tool tool = (Tool) this.getSession().get(Tool.class, toolDto.getId());
我必须首先调用commit()
(在与之前或之后的事务无关的会话上),即使给定的ID(此处由toolDto.getId()
确实存在< / strong>。我可以在数据库中看到它,但get()
不断返回null
,除非我再次呼叫commit()
:
首先发生这种情况:
HammerDTO hammerDto = toolSetDto.getHammer();
Hammer hammer = null;
if(hammerDto != null) {
ToolDTO toolDto = hammerDto.getTool();
ToolDescriptionDTO hammerDescriptionDto = toolDto.getToolDescription(languageDto.getId());
// Save new tool
ToolDescriptionDTO toolDescriptionDto = toolDescriptionRepository.save(storeDto, languageDto, toolDto, hammerDescriptionDto);
HammerRepository hammerRepository = new HammerRepository(this.getSessionId());
// Merge new tool into list of (in this case) hammers
hammer = hammerRepository.merge(storeDto, toolDescriptionDto.getToolDto());
}
我正在存储新工具及其说明。 **此部分有效,Tool
条目以及ToolDescription
条目在此之后出现:
public ToolDescriptionDTO save(StoreDTO storeDto, LanguageDTO languageDto, ToolDTO toolDto, ToolDescriptionDTO toolDescriptionDto) {
if(toolDto == null) {
throw new NullArgumentException("toolDto");
}
if(toolDescriptionDto == null) {
throw new NullArgumentException("toolDescriptionDto");
}
this.openSessionWithTransaction();
Tool tool = null;
ToolDescription toolDescription = null;
// First try to check if description exists if it does: load it otherwise: create new one
Long toolDescriptionId = toolDescriptionDto.getId();
if(toolDescriptionId != null) {
toolDescription = (ToolDescription) this.getSession().get(ToolDescription.class, toolDescriptionId);
tool = toolDescription.getTool();
}
if(tool == null) {
Language language = (Language) this.getSession().get(Language.class, languageDto.getId());
Store store = this.getStore(storeDto.getId());
tool = new Tool(store);
ConvertDTO.convertTool(tool, toolDto);
tool = (Tool) this.getSession().merge(tool);
toolDescription = new ToolDescription(tool, language);
}
ConvertDTO.convertToolDescription(toolDescription, toolDescriptionDto);
this.getSession().merge(toolDescription);
toolDescriptionDto = ConvertEntity.convertToolDescription(toolDescription);
this.closeSessionWithTransaction();
return toolDescriptionDto;
}
这是停止工作的部分,正如我所料。试图将“ Hammer ”添加到锤子列表中它只能在commit()
上与imho完全不相关的调用上完全不相关的调用:
public Hammer merge(ToolStoreDTO toolStoreDto, ToolDTO toolDto) {
this.openSession();
Criteria cr = this.getSession().createCriteria(Hammer.class);
cr.add(Restrictions.eq("toolStore.id", toolStoreDto.getId()));
cr.add(Restrictions.eq("tool.id", toolDto.getId()));
@SuppressWarnings("unchecked")
List<Hammer> hammers = cr.list();
Hammer hammer = null;
// IT ONLY WORKS WITH THIS COMMIT!
this.getSession().beginTransaction().commit(); // <----- ??
this.closeSession();
if(hammers.isEmpty() == false) {
hammer = hammers.get(0);
} else {
ToolStore toolStore = this.getToolStore(toolStoreDto.getId());
this.openSessionWithTransaction();
// Always 'null' if the commit above is not executed!
Tool tool = (Tool) this.getSession().get(Tool.class, toolDto.getId());
hammer = new Tool(toolStore, tool);
hammer = (Hammer) this.getSession().merge(tool);
this.closeSessionWithTransaction();
}
return hammer;
}
这对我没有意义。 我已提交(在之前的会话中)并且相应的条目确实存在。
这种行为可能是什么原因?
hibernate.cfg.xml中
<hibernate-configuration>
<session-factory>
<property name="connection.url">jdbc:mysql://localhost:3306/mahlzeit_db</property>
<property name="connection.username">root</property>
<property name="connection.password"></property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">false</property>
<property name="format_sql">false</property>
<!-- Run Hibernate in update mode -->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<property name="current_session_context_class">thread</property>
<!-- ... --->
</session-factory>
</hibernate-configuration>