1

I have this issue, I'm creating a Junit test and I want something to do first with setUp method. See my sample code:

class ClassDaoImplTests {

    @Autowired
    private NamedParameterJdbcTemplate template;

    private Project modifiedProject;
    
    private Project origProject;
    
    List<Project> projList;

    @BeforeAll
    protected void setUp() {
        
        preserveOriginalProjectData();
        prepareProjectDataToUpdate();
    }

    public void preserveOriginalProjectData() {
        
        projList = getSortedProjectList();
        origProject = projList.get(0);
    }
    
    public void prepareProjectDataToUpdate() {
        
        modifiedProject = projList.get(0);
        modifiedProject.setProjName(modifiedProject.getProjName() + "_Edit");
    }

    public List<Project> getSortedProjectList() {

        String sql = "SELECT * FROM Table1 ORDER BY id ASC";
        return template.query(sql, new BeanPropertyRowMapper<Project>(Project.class));
    }

}

Whatever I do with the modifiedProject, it reflects with origProject object and also the object inside the list. Even I use this kind of approached the result is the same:

 protected void setUp() {
    
    projList = getSortedProjectList();
    origProject = projList.get(0);
    prepareProjectDataToUpdate();
} 

How can I preserve the original object's data? I have not included other code's to minimize the size of code. But just stating the logic. Actually I want the origProject data for tearDown() to restore the values in the table.

talex
  • 17,973
  • 3
  • 29
  • 66
edmund
  • 31
  • 5
  • Pass the projList.element as value within prepareProjectDataToUpdate method or else create a new Variable for Project within prepareProjectDataToUpdate() – Mohit Hurkat Jul 20 '21 at 10:44
  • Thank you @talex. This gives me a new idea on how to have a separate copy by using clone. But on this phase where not allowed to change the models. For Mohit Hurat suggestion, I tried to pass it by making it parameter in prepareProjectDataToUpdate(Project project). But got same result. Not sure if I get your suggestion but Thank you. – edmund Jul 20 '21 at 11:58

1 Answers1

1

re: Whatever I do with the modifiedProject, it reflects with origProject object and also the object inside the list.

There is only one object here. Copying a reference does not copy the object referred to.

After this:

  modifiedProject = projList.get(0);

then 'modifiedProject' points to the object that is the first element of 'projList', not a copy of it. And of course 'origProject' points to that same object.

If you want a copy of a Project, then the Project class needs to provide a way to make a copy.


In your specific case, you may be able to sidestep that by executing the SELECT again, resulting in a separate instance. I'm not entirely sure about that, being unfamiliar with the database class you use, but it seems likely it retains nothing from one SQL statement to the next. Of course, that carries the risk that 'the first element in the sorted list' may not be the same as before, so I would not recommend that.

iggy
  • 1,328
  • 4
  • 3
  • I think that will be my work around. I executed the SELECT again in prepareProjectDataToUpdate() and by that I preserved the original data before modifiying it. Thank you so much. @iggy – edmund Jul 20 '21 at 11:54