我的实体没有坚持,但我可以从数据库中读取正常

时间:2012-07-23 16:49:51

标签: java spring hibernate transient

我刚刚更新到Hibernate 4.1.5和Spring 3.1.2(来自2.6ish和2.5或者其他......)。我已设法将everthing设置为从现有数据库中读取,并且所有页面都显示正常,但是在提交数据时,没有任何内容持久保存到数据库中。我已将日志记录设置为跟踪级别以尝试跟踪此问题,并且事务将归结为从我的日志中提取的以下15行:

DEBUG - org.hibernate.internal.SessionImpl - SessionImpl                    - Opened session at timestamp: 13430582784
TRACE - org.hibernate.internal.SessionImpl - SessionImpl                    - Setting flush mode to: AUTO
TRACE - org.hibernate.internal.SessionImpl - SessionImpl                    - Setting cache mode to: NORMAL
TRACE - org.hibernate.event.internal.AbstractSaveEventListener - AbstractSaveEventListener      - Transient instance of: ic.entities.MyEntity
TRACE - org.hibernate.event.internal.DefaultPersistEventListener - DefaultPersistEventListener    - Saving transient instance
TRACE - org.hibernate.event.internal.AbstractSaveEventListener - AbstractSaveEventListener      - Saving [ic.entities.MyEntity#<null>]
TRACE - org.hibernate.engine.spi.ActionQueue - ActionQueue                    - Adding an EntityIdentityInsertAction for [ic.entities.MyEntity] object
TRACE - org.hibernate.engine.spi.ActionQueue - ActionQueue                    - Adding insert with no non-nullable, transient entities: [EntityIdentityInsertAction[ic.entities.MyEntity#<delayed:0>]]
TRACE - org.hibernate.engine.spi.ActionQueue - ActionQueue                    - Adding resolved non-early insert action.
TRACE - org.hibernate.action.internal.UnresolvedEntityInsertActions - UnresolvedEntityInsertActions  - No unresolved entity inserts that depended on [[ic.entities.MyEntity#<delayed:0>]]
TRACE - org.hibernate.action.internal.UnresolvedEntityInsertActions - UnresolvedEntityInsertActions  - No entity insert actions have non-nullable, transient entity dependencies.
TRACE - org.hibernate.internal.SessionImpl - SessionImpl                    - Closing session
TRACE - org.hibernate.engine.jdbc.internal.LogicalConnectionImpl - LogicalConnectionImpl          - Closing logical connection
TRACE - org.hibernate.engine.jdbc.internal.JdbcResourceRegistryImpl - JdbcResourceRegistryImpl       - Closing JDBC container [org.hibernate.engine.jdbc.internal.JdbcResourceRegistryImpl@def577d]
TRACE - org.hibernate.engine.jdbc.internal.LogicalConnectionImpl - LogicalConnectionImpl          - Logical connection closed

我首先注意到它创建了一条日志消息:保存[ic.entities.MyEntity#&lt;空&GT]。但手动单步执行代码表明这是在id生成之前发生的,所以我猜它看起来像这样...我开始认为第10行和第11行是错误,但是在单步执行代码之后似乎这些是唯一没有抛出异常的有效代码路径,但是可以看出会话关闭并且没有保存任何条目......任何帮助将不胜感激!

我使用以下代码:

MyService.java

package ic.services;

import ic.entities.MyEntity;

import java.util.List;

public abstract class MyService extends BasicService<MyEntity>
{
    protected MyService()
    {
        super(MyEntity.class);
    }

    public abstract List<MyEntity> getAllByQuery(String query);
}

BasicService.java

package ic.services;

import java.io.Serializable;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

public abstract class BasicService<T extends Serializable>
{
    @PersistenceContext protected EntityManager em;
    private final Class<T> entityClass;

    protected BasicService(Class<T> entityClass)
    {
        this.entityClass = entityClass;
    }

    public T getEntity(Object primaryKey)
    {
        return em.find(entityClass, primaryKey);
    }

    public void persist(T entity)
    {
        em.persist(entity);
    }

    public void delete(T entity)
    {
        em.remove(entity);
    }
}

MyEntity.java

package ic.entities;

import java.util.Date;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity 
@Table
public class MyEntity implements Serializable
{
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String notes;
    private Date submittedDate;
    private boolean enabled;

    public Long getId()
    {
        return id;
    }

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

    public Date getSubmittedDate()
    {
        return submittedDate;
    }

    public void setSubmittedDate(Date submittedDate)
    {
        this.submittedDate = submittedDate;
    }

    public String getNotes()
    {
        return notes;
    }

    public void setNotes(String notes)
    {
        this.notes = notes;
    }

    public boolean isEnabled()
    {
        return enabled;
    }

    public void setEnabled(boolean enabled)
    {
        this.enabled = enabled;
    }

    @Override
    public boolean equals(Object obj) 
    {
        if(obj instanceof MyEntity)
        {
            MyEntity rhs = (MyEntity)obj;
            return rhs.id == this.id;
        }
        return false;
    }

    @Override
    public int hashCode()
    {
        return Long.valueOf(id).hashCode();
    }
}

并称之为:

@SpringBean MyService myService; //(Using wicket @Springbean)
...
MyEntity entity = new MyEntity();
entity.setEnabled(true);
entity.setNotes("blah");
entity.setSubmittedDate(new Date());
myService.persist(entity);

我的web.xml为:

<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <filter>
        <filter-name>OpenEntityManagerFilter</filter-name>
        <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>OpenEntityManagerFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

最后在applicationContext.xml中:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"></bean>

    <tx:annotation-driven/>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>

    <context:annotation-config />
    <context:component-scan base-package="ic.services" />
</beans>

再一次,任何帮助都会很棒。我敢肯定,这对我来说一定是非常愚蠢的事情! :)

1 个答案:

答案 0 :(得分:5)

尝试将@Transactional添加到您的持久服务方法。