3

Hibernate 4.1.5 および Spring 3.1.2 (2.6ish および 2.5 または何かから...) に更新しました。既存のデータベースから読み取るようにすべてを設定できましたが、すべてのページが正常に表示されますが、データを送信してもデータベースには何も保持されません。この問題を追跡するためにロギングをトレース レベルに設定しました。トランザクションは、ログから抽出された次の 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#< null>] を保存しています。しかし、コードを手動でステップ実行すると、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>

繰り返しますが、どんな助けも素晴らしいでしょう。私に代わって、それは信じられないほど愚かなことに違いないと確信しています!:)

4

1 に答える 1

5

永続化サービス メソッドに @Transactional を追加してみてください。

于 2012-07-23T18:27:11.550 に答える