1

データベースに入力する単純なフォームで構成されるタクシーを作成するページがあります。このクラスと dao は、休止状態ツールによって自動生成されました。persistコードを投稿し、それがメソッドと呼ばれると、コードを取得しPersistExceptionます。

コントローラー.java

@Controller
@RequestMapping(value="/session/taxi")
public class TaxiController {

private final Log log = LogFactory.getLog(getClass());
@Autowired
private UserManager userManager;
@Autowired 
private TaxiManager taxiManager;

/**
 * Returns the create taxi page.
 * @param model the model on which to map.
 * @return A String reference to jsp.
 */
@RequestMapping(value="/create", method=RequestMethod.GET)
public String createTaxi(ModelMap model){
    //Add the current business and city to this taxi. It can not be modified
    Taxi taxi = taxiManager.createDefaultTaxi();
    TaxiPassword taxiPass = new TaxiPassword();
    taxiPass.setTaxi(taxi);
    model.addAttribute("newTaxi", taxiPass);
    return "taxi/createtaxi";
}

/**
 * Add a new taxi to the database.
 * @param taxiPassword the taxi to be added.
 * @param result the result of binding taxi from the model.
 * @param redirectAttributes attributes to show messages when redirect.
 * @return a string that refers to jsp page.
 */
@RequestMapping(value="/create", method=RequestMethod.POST)
public String addNewTaxi(@ModelAttribute("newTaxi") @Valid TaxiPassword taxiPassword, BindingResult result, 
        final RedirectAttributes redirectAttributes){
    String newPage = "";
    Taxi taxi = taxiPassword.getTaxi();
    //Check password is correct
    if (!result.hasErrors()){
        //Set the password as md5
        taxi.setPassword(SecurityUtils.getMD5Password(taxi.getPassword()));
        //Persist it
        taxiManager.persistTaxi(taxiPassword.getTaxi());
        newPage = "redirect:/session/taxi/viewtaxi";
    }else{
        newPage = "taxi/createtaxi";
    }
    return newPage;
}

}

Taxi.java

@Entity
@Table(name = "taxi", catalog = "takeme", uniqueConstraints = @UniqueConstraint(columnNames = "username"))
public class Taxi implements java.io.Serializable {

    @NotNull
    @Size(min=1, max=20)
    @Digits(integer = 15, fraction = 0)
    private String idLicense;
    @Valid
    private City city;
    @Valid
    private Business business;
    @NotNull
    @Nif
    private String dni;
    @NotNull
    @Size(min=3, max=50)
    private String username;
    @Size(min=5, max=50)
    private String password;
    @NotNull
    @Size(min=1, max=50)
    private String name;
    @NotNull
    @Size(min=1, max=45)
    private String surname;
    @NotNull
    @Size(min=1, max=30)
    private String phone;
    @NotNull
    private boolean creditCardAvailability;
    @NotNull
    private boolean taxiAdapted;
    @NotNull
    private boolean bigTaxi;
    @NotNull
    private boolean availability;
    private Double latitude;
    private Double longitude;
    private byte[] photo;
    @NotNull
    private boolean state;
    private Set<Booking> bookings = new HashSet<Booking>(0);
    private Set<MobileClientRateTaxi> mobileClientRateTaxis = new HashSet<MobileClientRateTaxi>(
            0);

    public Taxi() {
    }

    public Taxi(String idLicense, City city, Business business, String dni,
            String username, String password, String name, String surname,
            String phone, boolean creditCardAvailability, boolean taxiAdapted,
            boolean bigTaxi, boolean availability, boolean state) {
        this.idLicense = idLicense;
        this.city = city;
        this.business = business;
        this.dni = dni;
        this.username = username;
        this.password = password;
        this.name = name;
        this.surname = surname;
        this.phone = phone;
        this.creditCardAvailability = creditCardAvailability;
        this.taxiAdapted = taxiAdapted;
        this.bigTaxi = bigTaxi;
        this.availability = availability;
        this.state = state;
    }

    public Taxi(String idLicense, City city, Business business, String dni,
            String username, String password, String name, String surname,
            String phone, boolean creditCardAvailability, boolean taxiAdapted,
            boolean bigTaxi, boolean availability, Double latitude,
            Double longitude, byte[] photo, boolean state,
            Set<Booking> bookings,
            Set<MobileClientRateTaxi> mobileClientRateTaxis) {
        this.idLicense = idLicense;
        this.city = city;
        this.business = business;
        this.dni = dni;
        this.username = username;
        this.password = password;
        this.name = name;
        this.surname = surname;
        this.phone = phone;
        this.creditCardAvailability = creditCardAvailability;
        this.taxiAdapted = taxiAdapted;
        this.bigTaxi = bigTaxi;
        this.availability = availability;
        this.latitude = latitude;
        this.longitude = longitude;
        this.photo = photo;
        this.state = state;
        this.bookings = bookings;
        this.mobileClientRateTaxis = mobileClientRateTaxis;
    }

    @Id
    @Column(name = "id_license", unique = true, nullable = false, length = 20)
    public String getIdLicense() {
        return this.idLicense;
    }

    public void setIdLicense(String idLicense) {
        this.idLicense = idLicense;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "id_city", nullable = false)
    public City getCity() {
        return this.city;
    }

    public void setCity(City city) {
        this.city = city;
    }

    // More autogenerated setters and getters...

}

TaxiDao.java

@Repository(value = "taxiDAO")
public class TaxiDAOImpl implements TaxiDAO{

    private final Log log = LogFactory.getLog(getClass());

    @PersistenceContext(unitName = "takemePU", type = PersistenceContextType.EXTENDED)
    private EntityManager entityManager;

    @Transactional(readOnly = false)
    public void persist(Taxi transientInstance) {
        log.debug("Persisting taxi instance: " + transientInstance.getIdLicense());
        try {
            entityManager.persist(transientInstance);
            log.debug("Persist successful");
        } catch (RuntimeException re) {
            log.error("Persist failed: ", re);
            throw re;
        }
    }

    @Transactional(readOnly = false, propagation=Propagation.REQUIRES_NEW)
    public void remove(Taxi persistentInstance) {
        log.debug("Removing taxi instance: " + persistentInstance.getIdLicense());
        try {
            entityManager.remove(persistentInstance);
            log.debug("Remove successful");
        } catch (RuntimeException re) {
            log.error("Remove failed: ", re);
            throw re;
        }
    }

    @Transactional(readOnly = false, propagation=Propagation.REQUIRES_NEW)
    public Taxi merge(Taxi detachedInstance) {
        log.debug("Merging taxi instance: " + detachedInstance.getIdLicense());
        try {
            Taxi result = entityManager.merge(detachedInstance);
            log.debug("Merge successful");
            return result;
        } catch (RuntimeException re) {
            log.error("Merge failed: ", re);
            throw re;
        }
    }

    @Transactional(readOnly = true)
    public Taxi findById(String id) {
        log.debug("Getting taxi instance with id: " + id);
        try {
            Taxi instance = entityManager.find(Taxi.class, id);
            log.debug("Get successful");
            return instance;
        } catch (RuntimeException re) {
            log.error("Get failed: ", re);
            throw re;
        }
    }

    @Transactional(readOnly = true)
    public Taxi findByUsername(String username) {
        log.debug("Getting taxi instance with id: " + username);
        try {
            Taxi instance = entityManager.find(Taxi.class, username);
            log.debug("Get successful");
            return instance;
        } catch (RuntimeException re) {
            log.error("Get failed: ", re);
            throw re;
        }
    }

    @SuppressWarnings("unchecked")
    @Transactional(readOnly = true)
    public List<Taxi> getTaxiList() {
        return entityManager.createQuery("select taxi from Taxi taxi").getResultList();
    }

    @SuppressWarnings("unchecked")
    @Transactional(readOnly = true)
    public List<Taxi> getTaxisByBusiness(String idBusiness) {
        return entityManager.createQuery("select taxi from Taxi taxi where taxi.business.idBusiness='"+ idBusiness+"'").getResultList();
    }
}

スタックトレースは次のとおりです。

javax.persistence.PersistenceException: org.hibernate.HibernateException: illegally attempted to associate a proxy with two open Sessions
org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1235)
org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1168)
org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1174)
org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:674)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:601)
org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:366)
com.sun.proxy.$Proxy90.persist(Unknown Source)
com.hp.unileon.takeme.dao.TaxiDAOImpl.persist(TaxiDAOImpl.java:36)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:601)
org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
com.sun.proxy.$Proxy100.persist(Unknown Source)
com.hp.unileon.takeme.service.SimpleTaxiManager.persistTaxi(SimpleTaxiManager.java:19)
com.hp.unileon.takeme.controller.TaxiController.addNewTaxi(TaxiController.java:112)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:601)
org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:838)
javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:183)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)

私が間違っていることを知るために構成ファイルが必要な場合は、教えてください。今のところ、それは膨大な量のコードだと思います(簡略化されています)。ありがとう。

更新:私のアプリケーションのコンテキストは:

<!-- Bean used by the daos to connect and make transactions with the database -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
p:entityManagerFactory-ref="entityManagerFactory"/>

<!-- Activate the annotation driven configurations making useful @Transaction annotations -->
<tx:annotation-driven transaction-manager="transactionManager"/>

<!-- Scans the classpath of this application for @Components to deploy as beans -->
<context:component-scan base-package="com.hp.unileon.takeme.service" />
<context:component-scan base-package="com.hp.unileon.takeme.dao" />

<!-- Holding properties for database connectivity -->
<context:property-placeholder location="classpath:jdbc.properties"/>

<!-- Enabling annotation driven configuration like @Component-->
<context:annotation-config/>

<!-- Selects the database data source giving username password and nedded parameters
to connect on it. You can change those parameters easily on /classes/messages.properties -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  <property name="driverClassName" value="${jdbc.driverClassName}"/>
  <property name="url" value="${jdbc.url}"/>
  <property name="username"  value="${jdbc.username}"/>
  <property name="password" value="${jdbc.password}"/>
</bean>

<!-- Element that loads tables on the database into object entities and so on -->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:dataSource-ref="dataSource"
p:jpaVendorAdapter-ref="jpaAdapter">
    <property name="loadTimeWeaver">
            <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
    </property>
    <!-- This persistence unit can be found on /main/resources/META-INF/persistence.xml -->                        
    <property name="persistenceUnitName" value="takemePU"></property>
</bean>

<!-- Enable hibernate to perform the database operations -->
<bean id="jpaAdapter"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
p:database="${jpa.database}"
p:showSql="${jpa.showSql}"/>
4

1 に答える 1

0

問題は に関連していPersistenceContextType.EXTENDEDます。拡張永続コンテキストを使用するデータベースからネストされたオブジェクトを取得すると、新しいセッションが開かれ、entityManager によって返されます。したがって、同じリクエストでそれらを使用し、Taxiそれらのネストされたオブジェクトをエンティティに追加しようとすると、 (スコープが であるため) クローズされていないセッションにCity属し、新しいセッションに属します。プロキシ遅延評価オブジェクトは異なるセッションに属しているため、Persist メソッドではこの種の動作を使用できません。BusinessEXTENDEDTaxi

私が最終的に見つけた解決策はOpenEntityManagerInViewFilter、同じセッション内のすべてのトランザクションに参加する を使用することです。これを行うには、このコードを web.xml に追加するだけです。

<filter>
    <filter-name>openEntityManagerInViewFilter</filter-name>
    <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
    <init-param>
        <param-name>entityManagerFactoryBeanName</param-name>
        <param-value>entityManagerFactory</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>openEntityManagerInViewFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
于 2013-04-28T12:36:07.553 に答える