问题是下面的代码片段没有删除数据库中的记录。
import org.hibernate.Session;
import org.hibernate.SessionFactory;
...
...
void deleteForm() {
Session session = sessionFactory.openSession();
FormDO formDO = new FormDO();
formDO.setId(formId);
session.delete(formDO); // No delete SQL query is getting fired.
然而,如果我打电话给session。flush()删除后,它可以完美地工作。请注意,我没有使用任何交易。
在Session类的JavaDoc中,delete方法的描述如下:
从数据存储中删除持久实例。参数可以是与接收会话相关联的实例,也可以是具有与现有持久状态相关联的标识符的瞬态实例。
我在网上看到了很多代码片段,它们表明在delete()之后不需要调用flush()。在这里的其他论坛上也提出了类似的问题,但仍未得到回答。
还有,会话。“保存”在没有会话的情况下可以正常工作。脸红
我使用的是HiberNate 4.2.16 Spring 4.0.9 JPA 1.0注解。以下是源文件供进一步参考,
java格式
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="form")
public class FormDO {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="id")
Integer id;
@Column(name="name")
String name;
...
...
Spring配置文件
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/tempdb" />
<property name="username" value="root" />
<property name="password" value="****" />
</bean>
<!-- Hibernate 4 SessionFactory Bean definition -->
<bean id="hibernate4AnnotatedSessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" >
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.test.FormDO</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.current_session_context_class">thread</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
FormDAO。JAVA
@Named
public class FormDAO {
@Inject
private SessionFactory sessionFactory;
public boolean deleteForm(Integer formId) {
Session session = sessionFactory.openSession();
FormDO formDO = new FormDO();
formDO.setId(formId);
session.delete(formDO);
session.flush(); // If this line is commented, record DOES NOT get deleted
return true;
}
public boolean saveForm(FormDO formDO) {
Session session = sessionFactory.openSession();
session.save(formDO); // Save doesn't require session.flush
return true;
}
...
...
更新:
我的困境很大程度上是由于不一致...session.save立即插入记录,但session.delete不会反映,除非显式调用flush()。但是当我提到Afsun发布的冲洗会话链接时,我的疑虑通过阅读下面的一行得到了澄清,
例外情况是,保存时会插入使用本机ID生成的对象。
我真的很感激大家给出的答案,因为几乎所有的答案都指向了正确的方向,但Afsun完全消除了我的疑虑。谢谢
flush()此方法强制当前会话刷新。必须在工作单元结束时调用,然后提交事务并关闭会话(取决于flush模式,Transaction.commit()调用此方法)。刷新是将基础持久存储与内存中的持久状态同步的过程。
因此,调用delete时需要刷新会话,否则被删除的记录仍将存在于基础数据库中 此外,您没有关闭正在打开的会话。当您开始使用池机制时,可能会出现这个问题。在大多数情况下,最佳做法是每次请求会话。关闭会话总是会将所有工作刷新到数据库中
您还需要在批处理中刷新,否则它可能会发出OutOfMemoryException。
从Hibernate会话类的Javadoc:
刷新是将底层持久存储与内存中的持久状态同步的过程。
当你呼叫会话时。delete()
告诉Hibernate从管理中删除实体。但是,相应的记录仍将存在于基础数据库中。你需要调用会话。flush()
以便将数据库与Hibernate会话同步。请注意,如果程序在没有调用会话的情况下结束。flush()
然后下次再次启动应用程序时,相关实体将重新出现。
通过Hibernate处理数据库时,您使用的是Hibernate会话
<代码>Hibernate会话通过以下三种情况刷新到数据库
commit()
-提交事务时会话时。flush()
这里最重要的是第二个。每次查询后都不会Hibernate会话
刷新数据库。如果我们通过Hibernate运行Native SQL查询
,Hibernate不知道刷新会话,或者如果运行HQL
,Hibernate也不知道刷新会话。对flush的调用将使会话状态与数据库同步请参见以下内容:在删除和刷新会话之前先Hibernate刷新
React引入了新的静态方法,它在每个呈现方法之前都会被调用,但为什么呢?在prop change之后调用它对我来说是有意义的,但是在之后调用它就没有意义了,也许我错过了什么。 我根据公司的要求创建了一个组件,在组件中日期是从道具控制的。我在组件中有以下状态。 是的,我在中创建了一个额外的变量来跟踪是否由于而被调用,但我认为这不是正确的方法。 或者是我做错了什么或者遗漏了什么,或者不应该在之后调用
问题内容: 我只是想简化我的一个类,并以与flyweight设计模式相同的样式介绍了一些功能。 但是,对于为什么总是调用after ,我有点困惑。我没想到这一点。谁能告诉我为什么会这样,否则我如何实现此功能?(除了将实现放入hack之外)。 这是一个例子: 输出: 为什么? 问题答案: 使用 时,你需要控制一个新实例的创建。 使用 时,你需要一个新的实例的控件初始化。 是实例创建的第一步。首先调用
本文向大家介绍为什么在__new __()之后总是调用__init __()?,包括了为什么在__new __()之后总是调用__init __()?的使用技巧和注意事项,需要的朋友参考一下 Python具有一种称为魔术方法的特殊类型的方法,该方法以前置和双下划线命名。 如果我们想谈论魔术方法__new__,那么显然也需要谈论__init__方法。创建实例时将调用魔术方法__new__。而在创建实
根据Spring Doc API http://docs.Spring.io/Spring-framework/docs/current/javadoc-api/index.html?org/springframework/web/context/contextloaderlistener.html- 这个(ContextLoaderListener)监听器应该注册在web.xml中的Log4jC
问题内容: 我只是想简化我的一个类,并以与flyweight设计模式相同的样式介绍了一些功能。 但是,对于为什么总是被称为after ,我有点困惑。我没想到这一点。谁能告诉我为什么会这样,否则我如何实现此功能?(除了将实现放到中之外)。 这是一个例子: 输出: 为什么? 问题答案: 使用时,你需要控制一个新实例的创建。 使用 时,你需要一个新的实例的控件初始化。 是实例创建的第一步。首先调用它,它
问题内容: 我正在尝试计算列表中值的平方和。以下是三个均计算所需值的变体。我想知道哪个是最有效的。我希望第三个装箱效率更高,因为自动装箱仅执行一次。 问题答案: 如有疑问,请测试!使用jmh,我在100k元素的列表上得到以下结果(以微秒为单位,更好): 因此,从快到慢,您已经拥有: 和 请注意,结果在很大程度上取决于JIT优化。如果映射中的逻辑更加复杂,则某些优化可能不可用(较长的代码=较少的内联