2

According to the definition of a immutable object (see this question), I am not pretty sure about whether making setters of a Spring DAO as a only-one-use is a way to assure immutability or not. For instance (dataSource property):

public class MySpringPojoDAO extends JdbcDaoSupport implements IMySpringPojoDAO {

   private boolean dataSourceSet = false;


   @Override
   public void setDataSource(DataSource dataSource){

       if (dataSourceSet) {
             throw new IllegalStateException("...");
       }

       dataSourceSet = true;
       this.dataSource = dataSource;
       }
   }

}

In the case it is wrong, what's the way to assure immutability using Spring Framework or IoC ?

Community
  • 1
  • 1
killabyte_garcia
  • 160
  • 1
  • 13

4 Answers4

4

Setters are ment to be used more than once, constructors on the other hand- are not.

When it comes to Spring, it's better to set all required beans through contructor:

final DataSource dataSource;// will force this property to be set only once

@Autowired(required=true)
public MySpringPojoDAO (DataSource dataSource){
   this.dataSource = dataSource;
}

Secondly you can simply add required attribute, that will make your code shorter. Spring will make sure a bean of DataSource is provided.

UPDATE: If you still want to use setters, than you don't need another flag, simply check !=null condition:

   @Override
   public void setDataSource(DataSource dataSource){
       if (this.dataSource != null) { // has been already set
             throw new IllegalStateException("...");
       }
       this.dataSource = dataSource;
   }
Beri
  • 11,470
  • 4
  • 35
  • 57
  • actually you do not need a variable `DataSource`. Look at `JdbcDaoSupport#getDataSource()` – alex Apr 28 '15 at 07:42
  • No, you don't :) I just wanted to explain, that when you want to set variable only once, using final can be a nice option. – Beri Apr 28 '15 at 07:44
  • ok I see. But if I provide no setter methods I do not need to make it final. Right? – alex Apr 28 '15 at 07:47
  • Yes, but making it final you will encourage compiler to remind you, that this property is not yet set, that's the only gist here:) And it won't compile otherway. – Beri Apr 28 '15 at 07:51
  • I'm pretty sure Spring calls `@Autowired`annotated methods only once. – alex Apr 28 '15 at 07:54
  • It is not about Spring, when having more than one property you can sometimes forget to put it inside the constructor, final will help you remember to do it, although it is more a way o styling your code:) – Beri Apr 28 '15 at 08:05
1

If you look at implementation of JdbcDaoSupport you will find this one:

public abstract class JdbcDaoSupport extends DaoSupport {

    private JdbcTemplate jdbcTemplate;


    /**
     * Set the JDBC DataSource to be used by this DAO.
     */
    public final void setDataSource(DataSource dataSource) {
        if (this.jdbcTemplate == null || dataSource != this.jdbcTemplate.getDataSource()) {
            this.jdbcTemplate = createJdbcTemplate(dataSource);
            initTemplateConfig();
        }
    }

    /**
    * Return the JDBC DataSource used by this DAO.
    */
    public final DataSource getDataSource() {
        return (this.jdbcTemplate != null ? this.jdbcTemplate.getDataSource() : null);
    }

    [...]

}

JdbcDaoSupport#setDataSource is final. You can not override this method. That means you have to do it in this way:

public class MySpringPojoDAO extends JdbcDaoSupport implements IMySpringPojoDAO {

    @Autowired
    public MySpringPojoDAO (DataSource dataSource){
        setDataSource(dataSource); // JdbcDaoSupport#setDataSource(..)
    }

    [...]

 }

So let Spring handle life cycle of the beans like DataSource for you. You should never manually create the instance of MySpringPojoDAO. Use instead:

@Autowired
private MySpringPojoDAO _myDao;
alex
  • 8,904
  • 6
  • 49
  • 75
0

Immutable objects are simply objects whose state (the object's data) cannot change after construction. Examples of immutable objects from the JDK include String and Integer.

To insure mutability of MySpringPojoDAO first make it final so it can not be extended second don introduce methods that can change its internal state like setters. And this is what I love about Spring and Guice Dependency injection, You can inject the constructor.

final public class MySpringPojoDAO extends JdbcDaoSupport implements IMySpringPojoDAO {

   // private boolean dataSourceSet = false; 

@Autowired
public MySpringPojoDAO (DataSource dataSource){
this.dataSource= dataSource
}
   /* @Override
   public void setDataSource(DataSource dataSource){

       if (dataSourceSet) {
             throw new IllegalStateException("...");
       }

       dataSourceSet = true;
       this.dataSource = dataSource;
       } */ 
       //don't use setters you'll need synchronization!!! 
   }

} 

check this out

Adelin
  • 18,144
  • 26
  • 115
  • 175
0

Immutable Objects

An object is considered immutable if its state cannot change after it is constructed. Maximum reliance on immutable objects is widely accepted as a sound strategy for creating simple, reliable code.

Immutable classes - java.lang.String, java.lang.Integer, java.lang.Byte, java.lang.Character, java.lang.Short, java.lang.Boolean, java.lang.Long, java.lang.Double, java.lang.Float ... etc

Classes which may / may not be final but not exactly fits the bill for (im)mutability - java.util.Collections, java.util.Arrays, etc.

IMHO, immutability is a good candidate for consideration - while defining a particular 'type' (entity - a Pojo type) of object. So while no-one will stop you creating your 'MySpringPojoDAO' immutable - it will make more sense if you implement 'MySpringPojo' immutable and the DAO as mutable. (or may be final)

read - https://stackoverflow.com/a/5124214/760393

Community
  • 1
  • 1
Raúl
  • 1,542
  • 4
  • 24
  • 37