2015-02-06 35 views
6

我需要在包級別上配置@TypeDefs以使用custom @Type。當我按照以下方式配置它時,我得到了ClassNotFoundException。但是,當我在類級別上放置@TypeDefs時,它工作正常。如何使用Spring Hibernate配置包級別@TypeDefs

我找到類似的stackoverflow post類似,但是我對如何用我的application-context.xml文件配置<resource package="com.foo.bar.thepackage"/>條目沒有任何想法。

根據一些後(如波紋管),指出此任何一個可以幫助我解決這個問題相關的bug

I believe this is due to a bug in Spring, where it doesn't scan the annotations in package-info, but only those on classes annotated with @Entity, @Embeddable, or @MappedSuperclass. See https://jira.springsource.org/browse/SPR-8589. 

一個春天。謝謝。

@TypeDefs聲明與package-info.java

@TypeDefs 
     ({ 
       @TypeDef(
         name="encryptedString", 
         typeClass=EncryptedStringType.class, 
         parameters={ 
           @Parameter(name="encryptorRegisteredName", 
             value="abcHibernateStringEncryptor") 
         } 
       ) 
     }) 

package com.abc.core.model; 

import org.hibernate.annotations.TypeDef; 
import org.hibernate.annotations.TypeDefs; 
import org.hibernate.annotations.Parameter; 
import org.jasypt.hibernate4.type.EncryptedStringType; 

應用程序的context.xml

<!-- ############################### General Configurations #################################################### --> 

<!-- Enable annotation-driven configuration and auto-detection --> 
<context:annotation-config/> 

<!-- Enable Spring configuration-detection --> 
<context:spring-configured/> 

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

<!-- Configure property placeholders for environment-specific properties customization --> 
<context:property-placeholder ignore-resource-not-found="true" location="classpath*:/project.properties"/> 


<!-- ############################### Persistence Related Configurations ######################################## --> 

<!-- JPA adapter --> 
<bean id="hibernateJpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> 
</bean> 

<!-- EntityManager factory --> 
<bean id="entityManagerFactory" 
     class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="dataSource" ref="dataSource" /> 
    <property name="jpaVendorAdapter" ref="hibernateJpaVendorAdapter" /> 
    <property name="packagesToScan" value="com.abc.core.model" /> 
    <property name="jpaProperties"> 
     <props> 
      <prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop> 
      <prop key="hibernate.dialect">org.hibernate.dialect.PostgresPlusDialect</prop> 
      <prop key="hibernate.hbm2ddl.auto">update</prop> 
      <prop key="hibernate.show_sql">false</prop> 
      <prop key="hibernate.format_sql">false</prop> 
      <prop key="hibernate.use_sql_comments">false</prop> 
      <prop key="hibernate.temp.use_jdbc_metadata_defaults">false</prop> 
      <prop key="hibernate.connection.autocommit">false</prop>     
     </props> 
    </property> 
</bean> 

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

<!-- JPA repositories --> 
<jpa:repositories base-package="com.abc" 
        transaction-manager-ref="transactionManager" 
        entity-manager-factory-ref="entityManagerFactory"/> 

<!-- Use @Transactional annotation on methods --> 
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/> 

<!-- ## JASYPT related configurations ## --> 

<!-- jasypt encryptor for string --> 
<bean id="abcStringEncryptor" 
     class="org.jasypt.encryption.pbe.StandardPBEStringEncryptor"> 
    <property name="algorithm"> 
     <value>PBEWithMD5AndDES</value> 
    </property> 
    <property name="password"> 
     <value>XXX</value> 
    </property> 
</bean> 

<!-- hibernate encryptor for string --> 
<bean id="theHibernateStringEncryptor" 
     class="org.jasypt.hibernate4.encryptor.HibernatePBEStringEncryptor"> 
    <property name="registeredName"> 
     <value>abcHibernateStringEncryptor</value> 
    </property> 
    <property name="encryptor"> 
     <ref bean="abcStringEncryptor" /> 
    </property> 
</bean> 

實體類的自定義映射@Type

package com.stee.rcm.core.model; 

@Entity 
@Table(name = "trail") 
public class Trail implements Serializable { 

    @Id 
    @GeneratedValue 
    @Column(name = "ID") 
    private Integer id; 

    @Type(type="encryptedString") 
    @Column(name = "DESCRIPTION") 
    private String description; 
} 

異常

Caused by: java.lang.ClassNotFoundException : encryptedString 
+0

任何人都有解決方案嗎? – 2017-11-10 13:40:09

回答

0

我也面臨着同樣的問題,這似乎春天有一些問題要掃描的TypeDef當他們在package-info.java類。

在配置中聲明資源不過是packagesToScan.You已經在您的配置中使用過,即使這樣也無助於掃描TypeDefs。

<resource package="com.foo.bar.thepackage"/> 

我們可以用以下任何方法去在每個POJO類

  1. 申報的TypeDef(其中曾經被用來USERTYPE/CustomType)。
  2. 將CustomType顯式註冊爲休眠配置。這可以通過兩種方式完成。

    1. Registering CustomType programmatic. 
        configuration.registerTypeOverride(new EncryptedStringType(),new String[]{"encryptedString"}); 
    
    2. Declaring TypeDef in session factory bean configuration and extending local session factory bean. 
    

Spring.xml:

<bean id="DateTypeSessionFactory" class="com.runtime.data.factory.TypeResolverSessionFactoryBean"> 
     <property name="dataSource" ref="DateTypeDataSource"/> 
     <property name="packagesToScan" value="com.p27.datetype"/> 
     <property name="customTypes"> 
      <array value-type="com.runtime.data.CustomType"> 
       <ref bean="dateTimeCustomType"/> 
      </array> 
     </property> 
     <property name="hibernateProperties"> 
      <props> 
       <prop key="hibernate.dialect"> 
        ${DateType.dialect} 
       </prop> 
       <prop key="hibernate.show_sql"> 
        false 
       </prop> 
       <prop key="hibernate.globally_quoted_identifiers"> 
        false 
       </prop> 
       <prop key="hibernate.hbm2ddl.auto"> 
        ${DateType.hbm2ddl} 
       </prop> 
      </props> 
     </property> 
    </bean> 

    <bean id="persistentLocalDateTimeType" class="com.studio.common.data.type.WMPersistentLocalDateTime"/> 
    <bean id="dateTimeCustomType" class="com.runtime.data.CustomType"> 
     <property name="type" ref="persistentLocalDateTimeType"/> 
     <property name="keys"> 
      <list> 
       <value>DateTime</value> 
       <value>org.joda.time.LocalDateTime</value> 
      </list> 
     </property> 
    </bean> 

    public class CustomType { 

    private UserType type; 
    private String[] keys; 

    //getters & setters 

    } 

SessionFactoryBean:

公共類TypeResolverSessionFactoryBean延伸的LocalSessionFactoryBean {

private CustomType[] customTypes; 

    @Override 
    protected SessionFactory buildSessionFactory(LocalSessionFactoryBuilder sfb) { 
     if(customTypes != null) { 
      registerCustomTypes(sfb); 
     } 
     return sfb.buildSessionFactory(); 
    } 

    protected void registerCustomTypes(LocalSessionFactoryBuilder sfb) { 
     for (CustomType customType : customTypes) { 
      sfb.registerTypeOverride(customType.getType(), customType.getKeys()); 
     } 
    } 

    public void setCustomTypes(CustomType[] customTypes) { 
     this.customTypes = customTypes; 
    } 
} 
相關問題