微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

java – Spring-Hibernate持久化不会导致插入

我正在尝试实现一个简单的DAO.
我有道:
@Repository("iUserDao")
@Transactional(readOnly = true)
public class UserDao implements IUserDao {
    private EntityManager entityManager;

    @PersistenceContext
    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    @Override
    public User getById(int id) {
        return entityManager.find(User.class,id);
    }

    @Override
    public boolean save(User user) {
        entityManager.persist(user);
        entityManager.flush();
        return true;
    }

    @Override
    public boolean update(User user) {
        entityManager.merge(user);
        entityManager.flush();
        return true;
    }

    @Override
    public boolean delete(User user) {
        user = entityManager.getReference(User.class,user.getId());
        if (user == null)
            return false;
        entityManager.remove(user);
        entityManager.flush();
        return true;
    }

一个实体:

@Entity
@Table(name = "users")
public class User {
    private int id;
    private Date creationDate;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public int getId() {
        return id;
    }

    public User() {
    }

    public User(Date creationDate) {
        this.creationDate = creationDate;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Date getCreationDate() {
        return creationDate;
    }

    public void setCreationDate(Date creationDate) {
        this.creationDate = creationDate;
    }
}

这是appContext.xml:
`

<bean id="entityManagerFactory"
      class="org.springframework.orm.jpa.LocalContainerEntityManagerfactorybean"
      p:dataSource-ref="dataSource" p:jpavendorAdapter-ref="jpaAdapter"
      p:persistenceUnitName="test">
    <property name="loadTimeweaver">
        <bean
                class="org.springframework.instrument.classloading.InstrumentationLoadTimeweaver"/>
    </property>
</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
      p:entityManagerFactory-ref="entityManagerFactory"/>
<bean id="jpaAdapter"
      class="org.springframework.orm.jpa.vendor.HibernateJpavendorAdapter"
      p:database="MysqL" p:showsql="true"/>

<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
<tx:annotation-driven/>`

除非我在persist()或merge()之后调用flush(),否则insert不会执行.
这是为什么?
如果我删除@Transactional然后我在刷新时遇到“没有事务正在进行中”的错误,但是如果删除了flush没有插入到DB中.

解决方法

它以这种方式工作,因为您使用@Transactional(readOnly = true)将事务标记为只读.

正如您所看到的,它不会使您的事务实际上是只读的,因为您仍然可以通过手动调用flush()来保持更改.但是,它会在事务结束时禁用自动刷新,因此如果没有手动刷新,则不会保留更改.

您需要从类级别注释中删除readOnly,或者在具有方法级注释的非只读方法上覆盖它:

@Override
@Transactional(readOnly = false)
public boolean save(User user) { ... }

另请注意,事务划分通常应用于服务层方法,而不是DAO方法.特别是,在编写DAO方法时,您实际上不知道哪些事务应该是只读的,哪些不是.此信息仅在设计服务层时可用,如本例中所示:

public class UserService {
    @Autowired UserDAO dao;

    @Transactional(readOnly = true) 
    public User getUserById(int id) {
        return dao.getById(id); // getById() can participate in effectively read-only transaction
    }

    @Transactional
    public void changeUserName(int id,String newName) {
        User u = dao.getById(id); // Or not
        u.setName(newName); // Change will be flushed at the end of transaction
    }
}

原文地址:https://www.jb51.cc/java/121949.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐