Avoid updating parent record when child objects merged

Usually in cascading, when the parent is set with collection of child objects and merged using session.saveOrUpdate(parent) or entityManager.merge(parent) , it usually updates the parent record after child records were inserted. This can be avoided using “updatable=false”.

@ManyToOne( fetch = FetchType.LAZY )
@Cascade( {CascadeType.PERSIST, CascadeType.MERGE} )
@JoinColumn( name = "<PARENT_ID>", updatable = false, 
                   referencedColumnName = "<PARENT_ID>" )
private Parent parent;
 
Advertisements

Create Blob in Hibernate

Blob field can be populated using  Hibernate.createBlob().

Map your persistent column to java.sql.Blob type.

    import java.sql.Blob;
    @Entity
    @Table( name = "BLOB_TEST" )
    public class BlobTable {
         // Id column goes here.
         
          @Column( name = "blob_col" )
         private Blob blobCol;
         
         // Getter and setter codes here
    }                   

Create blog using file.

 FileInputStream fis = new FileInputStream( "D:/export.txt" );
 BlobTable table = new BlobTable();
 table.setBlobCol( Hibernate.createBlob( fis ) );

PS: you can also use Hibernate.createBlob(byte[])

Persist the entity (BlobTable) using session.save(<ENTITY_OBJ>) (or) entityManager.persist(<ENTITY_OBJ>). Once persisted, verify the size of the blob column using the below SQL.

select dbms_lob.getlength(<BLOB_COL>) from <BLOB_TABLE>;

It should match the file size in bytes.

Spring application context aware

I want my spring application context to be retrieved any time anywhere in my application. Luckily, ApplicationContextAware and BeanFactoryPostProcessor helped me.

Spring-beans.xml:


<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:context="http://www.springframework.org/schema/context"

xmlns:jee="http://www.springframework.org/schema/jee"

xmlns:lang="http://www.springframework.org/schema/lang"

xmlns:tx="http://www.springframework.org/schema/tx"

xmlns:p="http://www.springframework.org/schema/p"

xmlns:util="http://www.springframework.org/schema/util"

xmlns:aop="http://www.springframework.org/schema/aop"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd

http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd

http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd

http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd

http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd

http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">

     <context:component-scan base-package="spring.examples"/>

</beans>  

Spring context Wrapper:

package spring.examples;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class SpringContextWrapper implements ApplicationContextAware,
        BeanFactoryPostProcessor {

    private ApplicationContext appContext;
    private ConfigurableListableBeanFactory factory;

    public void postProcessBeanFactory(ConfigurableListableBeanFactory factory)
            throws BeansException {
        this.factory = factory;
    }

    public void setApplicationContext(ApplicationContext c)
            throws BeansException {
        this.appContext = c;
    }
    public ApplicationContext getAppContext() {
        return appContext;
    }
    public void setAppContext(ApplicationContext appContext) {
        this.appContext = appContext;
    }
    public ConfigurableListableBeanFactory getFactory() {
        return factory;
    }
    public void setFactory(ConfigurableListableBeanFactory factory) {
        this.factory = factory;
    }
}

Test:

package spring.examples;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringContextWrapperTest {
    @Autowired
    SpringContextWrapper springContextWrapper;

    void createSpringContext() {
        AutowireCapableBeanFactory factory = null;
        ApplicationContext appContext = new ClassPathXmlApplicationContext("spring-beans.xml");
        factory = appContext.getAutowireCapableBeanFactory();
        factory.autowireBeanProperties(this,
                AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
    }
    public static void main(String[] args) {
        SpringContextWrapperTest springContextWrapperTest = new SpringContextWrapperTest();

        // Once Spring context is created, It will call the following post back methods in SpringContextWrapper
        // 1. postProcessBeanFactory
        // 2. setApplicationContext
        springContextWrapperTest.createSpringContext();

        // Check if the application context is injected in SpringContextWrapper.
        if (springContextWrapperTest.springContextWrapper.getAppContext() != null) {
            System.out.println("Application context is retreived from spring context wrapper.");
        } else {
            System.out.println("No Application context found.");
        }
    }
}

Output:

Inside setApplicationContext method
Inside postProcessBeanFactory method
Application context is retreived from spring context wrapper.

Now, I can able to retrieve spring application context anywhere in my application.

How to create spring beans dynamically?

Spring beans can be created dynamically using the following steps.

  1. Get the appropriate bean factory from application context.
  2. Get the bean definition registry from bean factory.
  3. Create your bean definition.
  4. Register the bean in the registry. 

Example Code:

import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class DynamicBeanTest {
    static ApplicationContext appContext = null;

    private void createDynamicBean() {
        AutowireCapableBeanFactory factory = null;
        appContext = new ClassPathXmlApplicationContext("spring-beans.xml");
        factory = appContext.getAutowireCapableBeanFactory();
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) factory;
        GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
        beanDefinition.setBeanClass(SampleBean.class);
        beanDefinition.setAutowireCandidate(true);
        registry.registerBeanDefinition("sampleBean", beanDefinition);
        factory.autowireBeanProperties(this,
                AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
    }

    public static void main(String[] args) {
        DynamicBeanTest dynamicBeanTest = new DynamicBeanTest();
        dynamicBeanTest.createDynamicBean();
        SampleBean sampleBean = getBean(SampleBean.class);
        sampleBean.method1();
    }

    @SuppressWarnings("unchecked")
    private static <T> T getBean(Class <? extends T> type) {
        String beanName = type.getSimpleName();
        beanName = beanName.substring(0, 1).toLowerCase()
                + beanName.substring(1);
        return (T) appContext.getBean(beanName);
    }
}

class SampleBean {

    public void method1() {
        System.out.println("Method1");
    }
}

Note: Ensure that spring-beans.xml is present in classpath before executing the above code.

Now you have invented how to define spring beans dynamically.

Enhancements in java.lang.Class and java.lang.reflect

The following methods in java.lang.Class were generified:

As a result, code which uses these methods now produces warnings during compilation.

For example, consider the following code which invokes getDeclaredMethod():

import java.lang.reflect.Method;

public class Warning {
    void m() {
        try {
            Warning warn = new Warning();
            Class c = warn.getClass();
            Method m = c.getDeclaredMethod("m");
        } catch (NoSuchMethodException x) {
            x.printStackTrace();
        }
    }
}

$ javac Warning.java

Note: Warning.java uses unchecked or unsafe operations.

Note: Recompile with -Xlint:unchecked for details.

$ javac -Xlint:unchecked Warning.java

Warning.java:8: warning: [unchecked] unchecked call to getDeclaredMethod(java.lang.String,java.lang.Class<?>…) as a member of the raw type java.lang.Class            

Method m = c.getDeclaredMethod(“m”);                                          

^ 1 warning

  • To remove the warning, the declaration of c should be modified to include an appropriate generic type. In this case, the declaration should be:
    Class<?> c = warn.getClass();
  • Hello World

    This is my first post. 

    public class HelloWorld {
     public static void main(String[] args) {
      System.out.println("Hello World");
     }
    }