2013-12-10 75 views
1

我正在使用Spring配置Hibernate 4。我有一個具有與@Type註解它的密碼性質的簡單用戶等級:Hibernate集成測試 - Jasypt加密跳過參數

@Entity 
@Table(name = "Users") 
public class User extends BaseEntity 
{ 
    @Column(name = "UserName", unique = true, length = 31) 
    @NotBlank(message = "User Name is required.") 
    @Size(min = 3, max = 31, message = "User Name must be between 3 and 31 characters in length.") 
    public String getUserName() 
    { 
     return userName; 
    } 

    public void setUserName(String userName) 
    { 
     this.userName = userName; 
    } 

    @Column(name = "Password", length = 511) 
    @Type(type = "org.jasypt.hibernate4.type.EncryptedStringType", parameters = { @Parameter(name = "encryptorRegisteredName", value = "passwordEncryptor") }) 
    @NotBlank(message = "Password is required") 
    public String getPassword() 
    { 
     return password; 
    } 

    public void setPassword(String password) 
    { 
     this.password = password; 
    } 
} 

我運行它使用HSQLDB作爲存儲引擎的集成測試。測試只是創建一個用戶的實例,並堅持下去。

問題是當用戶在堅持着,在密碼欄被完全排除在生成的SQL的:

2829 [main] DEBUG org.hibernate.SQL - insert into Users (Id, anonymous, Email, FirstName, LastName, Password, UserName) values (default, ?, ?, ?, ?, ?, ?) 
2829 [main] TRACE org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [1] as [BOOLEAN] - false 
2830 [main] TRACE org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [2] as [VARCHAR] - [email protected] 
2830 [main] TRACE org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [3] as [VARCHAR] - admin 
2830 [main] TRACE org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [4] as [VARCHAR] - admin 
3069 [main] TRACE org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [6] as [VARCHAR] - administrator 

正如你所看到的,插入語句有6個佔位符,和Hibernate只綁定5的參數。看看索引編號,你可以看到它跳過指數#5

這裏是我的Spring配置:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> 
    <property name="driverClassName" value="org.hsqldb.jdbcDriver" /> 
    <property name="url" value="jdbc:hsqldb:mem:ExampleTest" /> 
    <property name="initialSize" value="1" /> 
    <property name="maxActive" value="5" /> 
</bean> 

<bean id="sessionFactory" 
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource" /> 
    <property name="packagesToScan" value="com.my.entities" /> 
    <property name="hibernateProperties"> 
     <props> 
      <prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop> 
      <prop key="hibernate.show_sql">false</prop> 
      <prop key="hibernate.hbm2ddl.auto">update</prop> 
     </props> 
    </property> 
</bean> 

<bean id="transactionManager" 
    class="org.springframework.orm.hibernate4.HibernateTransactionManager"> 
    <property name="sessionFactory" ref="sessionFactory" /> 
</bean> 

<tx:annotation-driven /> 

<bean id="hibernateStringEncryptor" 
    class="org.jasypt.hibernate4.encryptor.HibernatePBEStringEncryptor"> 
    <property name="registeredName"> 
     <value>passwordEncryptor</value> 
    </property> 
    <property name="algorithm"> 
     <value>PBEWithMD5AndTripleDES</value> 
    </property> 
    <property name="password"> 
     <value>MY_PASSWORD_HERE</value> 
    </property> 
</bean> 

我做得不對或這是一個錯誤?

編輯:似乎發生了什麼並不是該列正在被跳過,它被添加到插入語句,它只是沒有被註銷(煩人)。真正的錯誤是使用錯誤的列長度(24而不是511)生成密碼列。

Caused by: org.hsqldb.HsqlException: data exception: string data, right truncation 
at org.hsqldb.error.Error.error(Unknown Source) 
at org.hsqldb.error.Error.error(Unknown Source) 

我打算調試hibernate代碼並找出發生了什麼。

+0

你是否嘗試在列中插入'insertable = true'? – nachokk

+0

不,我沒有,但我不認爲這是必要的。它在我使用MySQL5Dialect時正常工作,顯然不適用於HSQLDB。 – SoWeLie

回答

1

調試Hibernate代碼後,事實證明我的@Size驗證約束覆蓋了@Column(length = 511)註釋。因此,列生成長度爲24而不是511.

這可能是Hibernate中的一個錯誤,因爲JPA規範(according to this answer)說@Column註釋應該用於DDL,而@Size屬性應該僅用於驗證。至少,@Column應該覆蓋人們會認爲的@Size。特別是在這種情況下,我使用的UserType更改插入的字符串的大小。最後,爲了讓我的集成測試運行,我所做的只是通過添加「hibernate.validator.apply_to_ddl」屬性來告訴hibernate忽略集成測試項目中模式生成的驗證:

<bean id="sessionFactory" 
     class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource" /> 
    <property name="packagesToScan" value="com.myentities" /> 
    <property name="hibernateProperties"> 
     <props> 
      <prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop> 
      <prop key="hibernate.show_sql">false</prop> 
      <prop key="hibernate.hbm2ddl.auto">update</prop> 
      <prop key="hibernate.globally_quoted_identifiers">true</prop> 
      <!-- THIS LINE HERE --> 
      <prop key="hibernate.validator.apply_to_ddl">false</prop> 
     </props> 
    </property> 
</bean>