2

私はほとんどどこでも検索しましたが、誰もこの問題を抱えていないようです。Spring MVC アプリケーションがあります。コンテキスト構成ファイルでリクエスト スコープ Bean として宣言され、UsersController によって参照される UserImpl エンティティがあります。UsersController によって参照される UserImpl オブジェクトは、実際には CGLib プロキシです (理由は次のとおりです)。このようなプロキシ オブジェクトを HibernateTemplate で最初に永続化しようとしたときに、次のエラーが発生しました。

org.hibernate.MappingException: 不明なエンティティ: main.mvc.model.hibernate.UserImpl$$EnhancerByCGLIB$$9ac49631

いくつかの検索の後、私は次のようなものを見つけました:

org.springframework.orm.hibernate3.support.ScopedBeanInterceptor

問題をちょっと解決しました。今、私は MappingException を取得せず、エンティティは永続化されますが... データベース レコードのすべてのフィールドが null です。どうしたの?

注: UserImpl インスタンスをハードコーディングし、それを UserServiceImpl で永続化すると、すべて問題ありません。

コンテキスト構成の一部:

<bean id="userService" class="main.mvc.model.hibernate.UserServiceImpl"/>
<bean id="userValidator" class="main.validators.UserValidator"/>
<bean id="userWrapperValidator" class="main.validators.UserWrapperValidator"/>
<bean id="user" class="main.mvc.model.hibernate.UserImpl" scope="request">
    <aop:scoped-proxy/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="packagesToScan" value="main.mvc.model.hibernate"/>
    <property name="entityInterceptor">
<bean class="org.springframework.orm.hibernate3.support.ScopedBeanInterceptor"/>
    </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.hbm2ddl.auto">update</prop>
        </props>
    </property>
</bean>

ユーザーコントローラー:

package main.mvc.controllers;

import java.util.List;

import javax.inject.Inject;
import javax.validation.Valid;

import main.helpers.UserWrapper;
import main.mvc.model.User;
import main.mvc.model.UserService;
import main.mvc.model.hibernate.UserImpl;
import main.validators.UserValidator;
import main.validators.UserWrapperValidator;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;


@Controller
@RequestMapping("/users")
public class UsersController {

    private User user; // should be request-scoped
    private UserService userService;
    private UserValidator userValidator;
    private UserWrapperValidator userWrapperValidator;

    @SuppressWarnings("unused")
    private Logger logger = Logger.getLogger(getClass());

    @Inject
    public UsersController(User user, UserService userService, UserValidator userValidator, UserWrapperValidator userWrapperValidator){
        this.user = user;
        this.userService = userService;
        this.userValidator = userValidator;
        this.userWrapperValidator = userWrapperValidator;
    }

    @InitBinder("user")
    protected void setUserValidator(WebDataBinder binder){
        binder.setValidator(userValidator);
    }

    @InitBinder("userWrapper")
    protected void setUserWrapperValidator(WebDataBinder binder){
        binder.setValidator(userWrapperValidator);
    }

    @ModelAttribute
    public UserWrapper wrapUser(){
        return new UserWrapper(user);
    }

    //==================================REQUEST HANDLERS==========================================

    @RequestMapping(value={"/new"}, method=RequestMethod.GET)
    public String showCreationForm(@ModelAttribute UserWrapper userWrapper){
        return "user_registration_form";
    }

    @RequestMapping(method=RequestMethod.POST)
    public String createUser(@Valid @ModelAttribute UserWrapper userWrapper, BindingResult bindingResult, RedirectAttributes redirectAttributes){
        if(bindingResult.hasErrors()){
            return "user_registration_form";
        }
        userService.save(userWrapper.getUser());
        redirectAttributes.addFlashAttribute("message_title", "Jakiś text");
        redirectAttributes.addFlashAttribute("message_text", "Jakiś text");
        redirectAttributes.addFlashAttribute("redirect_url", "/users");
        return "redirect:information";
    }
...
}

UserServiceImpl:

public class UserServiceImpl extends HibernateDaoSupport implements UserService {

    private PasswordEncoder passwordEncoder;
    private SaltSource saltSource;

    @Inject
    public UserServiceImpl(SessionFactory sessionFactory, PasswordEncoder passwordEncoder, SaltSource saltSource) {
        super();
        setSessionFactory(sessionFactory);
        setPasswordEncoder(passwordEncoder);
        setSaltSource(saltSource);
    }

    public void save(User user) {
        Date creationTime = new Date();
        user.setCreationDate(creationTime);
        user.setLastModified(creationTime);

        List<Role> roles = new LinkedList<>();
        roles.add(Role.ROLE_USER);
        user.setRoles(roles);

        Logger.getLogger(getClass()).info(user);
        getHibernateTemplate().save(user);
    }
...
}

更新
OKなので、ScoppedBeanInterceptorで処理されている間にエンティティオブジェクトに何が起こるかをAOPマジックの追加出力に追加しました。無傷です。Hibernate の BasicBinder は null 値を SQL ステートメントにバインドしていますが。何か助けはありますか?

ログ:

11:27:51,866 DEBUG org.hibernate.SQL:111 - select userimpl0_.id as id1_, userimpl0_.creationDate as creation2_1_, userimpl0_.lastModified as lastModi3_1_, userimpl0_.city as city1_, userimpl0_.country as country1_, userimpl0_.latitude as latitude1_, userimpl0_.longitude as longitude1_, userimpl0_.postalCode as postalCode1_, userimpl0_.street as street1_, userimpl0_.birthDate as birthDate1_, userimpl0_.firstName as firstName1_, userimpl0_.secondName as secondName1_, userimpl0_.sex as sex1_, userimpl0_.surName as surName1_, userimpl0_.alias as alias1_, userimpl0_.enabled as enabled1_, userimpl0_.loginEmail as loginEmail1_, userimpl0_.password as password1_, userimpl0_.preferences_id as prefere19_1_ from TBL_USER userimpl0_ where userimpl0_.loginEmail=?
11:27:51,878 TRACE org.hibernate.type.descriptor.sql.BasicBinder:81 - binding parameter [1] as [VARCHAR] - blady_the_best@o2.pl
11:27:52,009  INFO hsqldb.db.HSQLDB39E3504C79.ENGINE:? - Database closed
11:27:52,225 DEBUG org.hibernate.SQL:111 - select userimpl0_.id as id1_, userimpl0_.creationDate as creation2_1_, userimpl0_.lastModified as lastModi3_1_, userimpl0_.city as city1_, userimpl0_.country as country1_, userimpl0_.latitude as latitude1_, userimpl0_.longitude as longitude1_, userimpl0_.postalCode as postalCode1_, userimpl0_.street as street1_, userimpl0_.birthDate as birthDate1_, userimpl0_.firstName as firstName1_, userimpl0_.secondName as secondName1_, userimpl0_.sex as sex1_, userimpl0_.surName as surName1_, userimpl0_.alias as alias1_, userimpl0_.enabled as enabled1_, userimpl0_.loginEmail as loginEmail1_, userimpl0_.password as password1_, userimpl0_.preferences_id as prefere19_1_ from TBL_USER userimpl0_ where userimpl0_.alias=?
11:27:52,230 TRACE org.hibernate.type.descriptor.sql.BasicBinder:81 - binding parameter [1] as [VARCHAR] - Bladositto
11:27:52,346  INFO hsqldb.db.HSQLDB39E3504C79.ENGINE:? - Database closed
11:27:52,470  INFO model.hibernate.UserServiceImpl:50 - User[id: null    loginEmail: blady_the_best@o2.pl    alias: Bladositto   password: asdasd]   class type:class model.hibernate.UserImpl$$EnhancerByCGLIB$$536b42dd
11:27:52,481  INFO helpers.EntityAuditor:13 - User[id: null  loginEmail: blady_the_best@o2.pl    alias: Bladositto   password: asdasd]
11:27:52,483  INFO helpers.EntityAuditor:13 - User[id: null  loginEmail: blady_the_best@o2.pl    alias: Bladositto   password: asdasd]
11:27:52,581 DEBUG org.hibernate.SQL:111 - insert into TBL_USER (id, creationDate, lastModified, city, country, latitude, longitude, postalCode, street, birthDate, firstName, secondName, sex, surName, alias, enabled, loginEmail, password, preferences_id) values (default, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
11:27:52,587 TRACE org.hibernate.type.descriptor.sql.BasicBinder:70 - binding parameter [1] as [TIMESTAMP] - <null>
11:27:52,589 TRACE org.hibernate.type.descriptor.sql.BasicBinder:70 - binding parameter [2] as [TIMESTAMP] - <null>
11:27:52,590 TRACE org.hibernate.type.descriptor.sql.BasicBinder:70 - binding parameter [3] as [VARCHAR] - <null>
11:27:52,604 TRACE org.hibernate.type.descriptor.sql.BasicBinder:70 - binding parameter [4] as [VARCHAR] - <null>
11:27:52,606 TRACE org.hibernate.type.descriptor.sql.BasicBinder:70 - binding parameter [5] as [DOUBLE] - <null>
11:27:52,609 TRACE org.hibernate.type.descriptor.sql.BasicBinder:70 - binding parameter [6] as [DOUBLE] - <null>
11:27:52,610 TRACE org.hibernate.type.descriptor.sql.BasicBinder:70 - binding parameter [7] as [VARCHAR] - <null>
11:27:52,611 TRACE org.hibernate.type.descriptor.sql.BasicBinder:70 - binding parameter [8] as [VARCHAR] - <null>
11:27:52,612 TRACE org.hibernate.type.descriptor.sql.BasicBinder:70 - binding parameter [9] as [DATE] - <null>
11:27:52,614 TRACE org.hibernate.type.descriptor.sql.BasicBinder:70 - binding parameter [10] as [VARCHAR] - <null>
11:27:52,615 TRACE org.hibernate.type.descriptor.sql.BasicBinder:70 - binding parameter [11] as [VARCHAR] - <null>
11:27:52,616 DEBUG org.hibernate.type.EnumType:136 - Binding null to parameter: 12
11:27:52,618 TRACE org.hibernate.type.descriptor.sql.BasicBinder:70 - binding parameter [13] as [VARCHAR] - <null>
11:27:52,619 TRACE org.hibernate.type.descriptor.sql.BasicBinder:70 - binding parameter [14] as [VARCHAR] - <null>
11:27:52,621 TRACE org.hibernate.type.descriptor.sql.BasicBinder:70 - binding parameter [15] as [BIT] - <null>
11:27:52,621 TRACE org.hibernate.type.descriptor.sql.BasicBinder:70 - binding parameter [16] as [VARCHAR] - <null>
11:27:52,623 TRACE org.hibernate.type.descriptor.sql.BasicBinder:70 - binding parameter [17] as [VARCHAR] - <null>
11:27:52,625 TRACE org.hibernate.type.descriptor.sql.BasicBinder:70 - binding parameter [18] as [BIGINT] - <null>
11:27:52,767  INFO hsqldb.db.HSQLDB39E3504C79.ENGINE:? - Database closed
4

1 に答える 1

1

「不明なエンティティ」ビットは、デフォルトで Hibernate が渡されたオブジェクトのクラスを参照するだけであるためです。Hibernate はこの Spring 拡張クラスについて何も知りません。org.hibernate.EntityNameResolverHibernate の用語では、カスタム エンティティの名前解決を許可するコントラクトを登録する必要があります。本当にSpringはおそらくそれを登録する必要がありますが、それは些細なことです;)

または、save() et の形式を呼び出すこともできます。アル。エンティティ名を受け入れます。たとえば、次の代わりに:

getHibernateTemplate().save( user );

代わりにこれを使用してください:

getHibernateTemplate().save( User.class.getName(), user );

(Spring の HibernateTemplate が実際にこれらのメソッドを公開すると仮定します。これは、テンプレート クラスでの私の経験を考えると、実際には非常に大きな仮定です)。

于 2012-09-02T14:47:41.650 に答える