0

I am working on a Spring-MVC application which uses Hibernate as an ORM tool. We would like to encrypt some columns and for that I am using Jasypt. Now, for that I have to use the annotation @Type, but it requires that there should be a hibernate.cfg.xml file present. Unfortunately, I am not using hibernate.cfg.xml and my sessionFactory and all other configuration are defined in applicationServletContext.xml and root-context.xml.

These are the types I want to use : Filename : jasyptHibernateTypes.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

    <!-- VARCHAR, CLOB, TEXT based types -->

    <typedef name="encryptedString" class="org.jasypt.hibernate.type.EncryptedStringType">
        <param name="encryptorRegisteredName">jasyptHibernateEncryptor</param>
    </typedef>

    <typedef name="encryptedBigDecimalAsString" class="org.jasypt.hibernate.type.EncryptedBigDecimalAsStringType">
        <param name="encryptorRegisteredName">jasyptHibernateEncryptor</param>
    </typedef>

    <typedef name="encryptedBigIntegerAsString" class="org.jasypt.hibernate.type.EncryptedBigIntegerAsStringType">
        <param name="encryptorRegisteredName">jasyptHibernateEncryptor</param>
    </typedef>

    <typedef name="encryptedBooleanAsString" class="org.jasypt.hibernate.type.EncryptedBooleanAsStringType">
        <param name="encryptorRegisteredName">jasyptHibernateEncryptor</param>
    </typedef>

    <typedef name="encryptedByteAsString" class="org.jasypt.hibernate.type.EncryptedByteAsStringType">
        <param name="encryptorRegisteredName">jasyptHibernateEncryptor</param>
    </typedef>

    <typedef name="encryptedCalendarAsString" class="org.jasypt.hibernate.type.EncryptedCalendarAsStringType">
        <param name="encryptorRegisteredName">jasyptHibernateEncryptor</param>
    </typedef>

    <typedef name="encryptedDateAsString" class="org.jasypt.hibernate.type.EncryptedDateAsStringType">
        <param name="encryptorRegisteredName">jasyptHibernateEncryptor</param>
    </typedef>

    <typedef name="encryptedDoubleAsString" class="org.jasypt.hibernate.type.EncryptedDoubleAsStringType">
        <param name="encryptorRegisteredName">jasyptHibernateEncryptor</param>
    </typedef>

    <typedef name="encryptedFloatAsString" class="org.jasypt.hibernate.type.EncryptedFloatAsStringType">
        <param name="encryptorRegisteredName">jasyptHibernateEncryptor</param>
    </typedef>

    <typedef name="encryptedIntegerAsString" class="org.jasypt.hibernate.type.EncryptedIntegerAsStringType">
        <param name="encryptorRegisteredName">jasyptHibernateEncryptor</param>
    </typedef>

    <typedef name="encryptedLongAsString" class="org.jasypt.hibernate.type.EncryptedLongAsStringType">
        <param name="encryptorRegisteredName">jasyptHibernateEncryptor</param>
    </typedef>

    <typedef name="encryptedShortAsString" class="org.jasypt.hibernate.type.EncryptedShortAsStringType">
        <param name="encryptorRegisteredName">jasyptHibernateEncryptor</param>
    </typedef>


    <!-- VARBINARY, BLOB based type -->
    <typedef name="encryptedBinary" class="org.jasypt.hibernate.type.EncryptedBinaryType">
        <param name="encryptorRegisteredName">jasyptByteHibernateEncryptor</param>
    </typedef>

    <!-- NUMERIC, NUMBER based types -->
    <typedef name="encryptedBigDecimal" class="org.jasypt.hibernate.type.EncryptedBigDecimalType">
        <param name="encryptorRegisteredName">jasyptBigDecimalHibernateEncryptor</param>
    </typedef>

    <typedef name="encryptedBigInteger" class="org.jasypt.hibernate.type.EncryptedBigIntegerType">
        <param name="encryptorRegisteredName">jasypBigIntegertHibernateEncryptor</param>
    </typedef>



</hibernate-mapping>

Here is my root-context.xml :

<context:component-scan base-package="com.journaldev.spring">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <context:property-placeholder location="classpath:application.properties"/>

    <beans:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
                destroy-method="close">
        <beans:property name="driverClassName" value="org.postgresql.Driver"/>
        <beans:property name="url"
                        value="jdbc:postgresql://localhost:5432/dbname"/>
        <beans:property name="username" value="postgres"/>
        <beans:property name="password" value="password"/>
        <beans:property name="removeAbandoned" value="true"/>
        <beans:property name="removeAbandonedTimeout" value="20"/>
        <beans:property name="defaultAutoCommit" value="false"/>
    </beans:bean>

    <!-- Hibernate 4 SessionFactory Bean definition -->
    <beans:bean id="hibernate4AnnotatedSessionFactory"
                class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <beans:property name="dataSource" ref="dataSource"/>
        <beans:property name="packagesToScan" value="com.journaldev.spring.model"/>

        <beans:property name="hibernateProperties">
            <beans:props>
                <beans:prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQL9Dialect</beans:prop>
                <beans:prop key="hibernate.show_sql">false</beans:prop>
                <!--   <beans:prop key="hibernate.jdbc.batch_size">1000</beans:prop>
                   <beans:prop key="hibernate.order_updates">true</beans:prop>-->
                <beans:prop key="hibernate.hbm2ddl.auto">update</beans:prop>
                <beans:prop key="cache.use_second_level_cache">true</beans:prop>
                <beans:prop key="cache.use_query_cache">true</beans:prop>
            </beans:props>
        </beans:property>
    </beans:bean>

    <beans:bean id="LoginServiceImpl" class="com.journaldev.spring.service.LoginServiceImpl"/>

    <task:annotation-driven/>

    <tx:annotation-driven transaction-manager="transactionManager"/>

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

 <beans:bean id="stringEncryptor"  class="org.jasypt.encryption.pbe.StandardPBEStringEncryptor" lazy-init="false">
        <beans:property name="algorithm" value="PBEWithMD5AndDES" />
        <beans:property name="password" value="password" />
    </beans:bean>

    <beans:bean id="hibernateEncryptor" class="org.jasypt.hibernate.encryptor.HibernatePBEStringEncryptor" lazy-init="false">
        <!-- This property value must match "encryptorRegisteredName" used when defining hibernate user types -->
        <beans:property name="registeredName" value="jasyptHibernateEncryptor" />
        <beans:property name="encryptor" ref="stringEncryptor" />
    </beans:bean>

As you can see, my major config is in this file, and I have also put the interceptors here. I am getting this error :

Caused by: org.hibernate.MappingException: Could not determine type for: encryptedString
    at org.hibernate.cfg.annotations.SimpleValueBinder.fillSimpleValue(SimpleValueBinder.java:516)
    at org.hibernate.cfg.SetSimpleValueTypeSecondPass.doSecondPass(SetSimpleValueTypeSecondPass.java:42)
    at org.hibernate.cfg.Configuration.processSecondPassesOfType(Configuration.java:1472)
    at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1420)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1846)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1930)
    at org.springframework.orm.hibernate4.LocalSessionFactoryBuilder.buildSessionFactory(LocalSessionFactoryBuilder.java:372)
    at org.springframework.orm.hibernate4.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:454)
    at org.springframework.orm.hibernate4.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:439)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1633)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1570)
    ... 98 more
Caused by: org.hibernate.annotations.common.reflection.ClassLoadingException: Unable to load Class [encryptedString]
    at org.hibernate.annotations.common.util.StandardClassLoaderDelegateImpl.classForName(StandardClassLoaderDelegateImpl.java:60)
    at org.hibernate.cfg.annotations.SimpleValueBinder.fillSimpleValue(SimpleValueBinder.java:497)
    ... 108 more
Caused by: java.lang.ClassNotFoundException: encryptedString
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1720)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1571)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:348)
    at org.hibernate.annotations.common.util.StandardClassLoaderDelegateImpl.classForName(StandardClassLoaderDelegateImpl.java:57)
    ... 109 more

Model class:

 @Column(name = "mnotetext")
    @Type(type="encryptedString")
    private String mnotetext;

    @Column(name = "mnoteheadline")
    @Type(type="encryptedString")
    private String mnotetag;

What should I do to use the types without hibernate.cfg.xml. How to instruct hibernate that they are in this xml file. Thanks a lot. :-)

Update

Model class :

@TypeDef( name = "registeredName",
        defaultForType = org.jasypt.hibernate.type.EncryptedStringType.class,
        typeClass = org.jasypt.hibernate.type.EncryptedStringType.class)
@Entity
@Table(name = "groupnotes")
public class GroupNotes implements Serializable{
 @Column(name = "mnotetext")
    @Type(type="registeredName")
    private String mnotetext;

    @Column(name = "mnoteheadline")
    @Type(type="registeredName")
    private String mnotetag;
}

New error log :

Caused by: org.hibernate.MappingException: Unable to instantiate custom type: org.jasypt.hibernate.type.EncryptedStringType
    at org.hibernate.type.TypeFactory.custom(TypeFactory.java:218)
    at org.hibernate.type.TypeFactory.custom(TypeFactory.java:204)
    at org.hibernate.type.TypeFactory.byClass(TypeFactory.java:103)
    at org.hibernate.type.TypeResolver.heuristicType(TypeResolver.java:130)
    at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:340)
    at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:322)
    at org.hibernate.mapping.Property.isValid(Property.java:241)
    at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:496)
    at org.hibernate.mapping.RootClass.validate(RootClass.java:270)
    at org.hibernate.cfg.Configuration.validate(Configuration.java:1360)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1851)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1930)
    at org.springframework.orm.hibernate4.LocalSessionFactoryBuilder.buildSessionFactory(LocalSessionFactoryBuilder.java:372)
    at org.springframework.orm.hibernate4.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:454)
    at org.springframework.orm.hibernate4.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:439)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1633)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1570)
    ... 98 more
Caused by: org.jasypt.exceptions.EncryptionInitializationException: If "encryptorRegisteredName" is not specified, then "password" (and optionally "algorithm" and "keyObtentionIterations") must be specified
    at org.jasypt.hibernate.type.AbstractEncryptedAsStringType.setParameterValues(AbstractEncryptedAsStringType.java:226)
    at org.hibernate.type.TypeFactory.injectParameters(TypeFactory.java:131)
    at org.hibernate.type.TypeFactory.custom(TypeFactory.java:214)
    ... 114 more
We are Borg
  • 5,117
  • 17
  • 102
  • 225
  • I declared the TypeDef annotation, but that is giving me error related to it. I have updated my main-post, and at bottom included both. Please check the bottom model and error. – We are Borg Oct 01 '15 at 15:45

1 Answers1

1

I think your problem is how you declare your custom type. However it's possible to define type using annotations take a look at the documentation: 5.1.4.1.1. Type

@TypeDef( name = "registeredName",
    defaultForType = org.jasypt.hibernate.type.EncryptedStringType.class,
    typeClass = org.jasypt.hibernate.type.EncryptedStringType.class,
    parameters = {
        @Parameter(name="algorithm", value="PBEWithMD5AndTripleDES"),
        @Parameter(name="password", value="password"),
        @Parameter(name="keyObtentionIterations", value="1000")
    }
)

You can't use any bean in this.

JEY
  • 6,973
  • 1
  • 36
  • 51
  • Thank you for your answer, I declared the TypeDef annotation, but that is giving me error related to it. I have updated my main-post, and at bottom included both. Can you kindly check. Thanks a lot. :-) – We are Borg Oct 01 '15 at 15:45
  • it can't instanciate the type because If "encryptorRegisteredName" is not specified, then "password" (and optionally "algorithm" and "keyObtentionIterations") must be specified. You need to give some parameters. – JEY Oct 01 '15 at 15:47
  • This is specified in the root-context.xml I have. If not there, how can I specify it in model? I am sorry I might sound like a noob, but I have never worked on cryptography before or this framework. Can you please check the root-context.xml which I have in main post. Thank you. – We are Borg Oct 01 '15 at 15:49
  • Thanks man, This worked, just one last thing, I am getting java.lang.NoClassDefFoundError: org/hibernate/util/EqualsHelper . This is because EqualsHelper is in old Hibernate-core. Any ideas: THanks a lot man. :-) – We are Borg Oct 01 '15 at 16:06
  • No you can always create it in your project. Don't forget to accept answer – JEY Oct 02 '15 at 06:02
  • I will surely accept it, can you just clarify what do you mean by accept it in your project? Maven complains about duplicate dependencies if I put an old hibernate-core version. – We are Borg Oct 02 '15 at 07:10
  • first of all check compatibility between hibernate and jasypt. If there is just this one class you can create it in your project within the same package and same name and same method and implement the behavior. – JEY Oct 02 '15 at 07:15
  • Okay. Thanks a lot my friend.. :-) – We are Borg Oct 02 '15 at 07:15
  • What I did was to solve the hibernate-core problem was to update the maven dependency from jasypt-hibernate3 to jasypt-hibernate4. Incase if you wanted to know.. :-) – We are Borg Oct 02 '15 at 07:46
  • Hi, Can you please check this question about Jasypt my friend : http://stackoverflow.com/questions/32906788/java-jasypt-how-can-i-encrypt-db-password-and-type-password-without-hibernat . Thanks a lot.. :-) – We are Borg Oct 02 '15 at 12:08