I am using Hibernate 4, configured with Spring. I have a simple User class that has its password property annotated with the @Type annotation:
@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;
}
}
I am running an integration test which uses HSQLDB as the storage engine. The test just creates an instance of User, and persists it.
The problem is when the user is persisted, the password column is completely left out of the generated 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] - admin@testing.com
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
As you can see, the insert statement has 6 placeholders, and Hibernate is only binding five of the parameters. Look at the index numbers, you can see it is skipping index # 5.
Here is my spring configuration:
<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>
Am I doing something wrong or is this a bug?
EDIT: It seems that what is happening isn't that the column is being skipped, it is being added to the insert statement, it's just not being logged out (annoying). The real error is the Password column is being generated with the wrong column length (24 instead of 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)
I am going to debug the hibernate code and figure out what is going on.