Should I make the object mutable? - java

I have a service A which listens for messages from a Queue and calls another service B to get some values assume val1...x.
Assuming my entity is
Entity
|- val1
|- val2
|
... val1n
The values from both the service B populates assume x vals in the entity.
And after the service call service A computes some values and populates other fields in the entity.
Possible approaches for modeling the Entity
[1] Make Entity immutable and make every update to the entity copy all values 1...x to make a new object.
[2] Make Entity partially immutable like declaring val1...x final and others non-final, so I can use setters to set the values on them.
EDIT : [3] Keep passing around Builder Object and when all values val1...n has been populated call the build() function.
EDIT2 : [4] Have two separate object (private inner) immutable - val1...x and immutable valx..n. Everytime some update happens on the valx..n I will create new copy of mutable object and refer to the immutable one.

If I understand correctly you are willing to create object in one service, populate some of the fields, than pass it to another service, and populate rest of them? After this, the object is complete?
If so, I would use Builder patter, populating fields of builer and once it's complete - build immutable object

Make service B return an immutable value object (let's call it ExtendedEntityInformation), then use the values from service A and that object to create your immutable Entity. You might even just store the ExtendedEntityInformation object in your Entity and if needed, implement getters on Entity that delegate to getters in ExtendedEntityInformation.

Related

Should a repository always return the same reference in memory when querying for the same ID?

In many blogs or articles one reads the following statement about the repository
You should think of a repository as a collection of domain objects in memory
Now i am asking myself what should happen when i query the repository for the same Id twice.
Entity a = theRepo.GetById(1);
Entity b = theRepo.GetById(1);
assertTrue( a == b ); // Do they share the same reference ?
assertTrue( a.equals( b ) ); // This should always be true
Should the repository always return the same reference in memory ?
Should the repository return a new instance of the entity but with equal state?
I don't think you can assume that a == b.
Consider the situation where you got instance a, and started to modify it, not yet saving it back to your database. If another thread requests the same entity and puts it in variable b, it should get a new one reflecting the data in the database, not a dirty one that another thread is modifying and hasn't yet (and possibly never will) save.
On the other hand, assuming that a or b has not been subsequently modified after it has been retrieved from the same repository, it should be safe to assume that a.equals(b), also assuming that the equals() method has been implemented correctly for the entity.
In my opinion, your problem boils down to the lifespan of the repository. Repositories are transient (ideally) and also, sometimes, they live inside another class called "Unit of Work" which is transient as well.
I don't think this is a DDD issue, but more of an Infrastructure issue.
Given an entity type, a repository is a collection of instances of a the given entity type.
A repository doesn't create instances of the entity. It is just a collection (in the sense of a "set") of instances that you created before. Then you add those instances to the repository (set of instances). And you can retrieve those instances.
A set doesn't duplicate elements. Given an id (eg id=1), the set will just have one instance with id=1, and that instance is the one you retrieve when you call "theRepo.GetById(1)".
So:
Entity a = theRepo.GetById(1);
Entity b = theRepo.GetById(1);
Should the repository always return the same reference in memory ?
See UPDATE 3.
Should the repository return a new instance of the entity but with
equal state?
No. The repository should return the instance that you added before. The repository shouldn't create new instances.
Anyway, in order to check whether two instances are the same, you shouldn't compare the references, you should compare their ids.
You are mixing concepts. A repository is just a collection (set) of instances. Instances are created by factories (or by constructor methods of the entity).
See IDDD book by Vaughn Vernon ("Collection-Oriented Repositories" section in Chapter 12).
Hope it helps.
UPDATE:
When I say "...Repository is a set of instances..." I mean it mimics a set. My fault not expressing it well. Regarding to update an instance of the repository, such operation doesn't exist, since when you retrieve an instance and modify it, the changes are made in the instance of the repository, you don't have to re-save the instance. The peristence mechanism implemeting the repository must have capabilities to ensure this behaviour. See Chapter 12 of the Implementing DDD book by Vaugn Vernon.
UPDATE 2:
I want to clarify that what I say here is my understanding after reading Vaughn Vernon book IDDD, and also another book (Domain Driven Design in PHP, by Carlos Buenosvinos). I'm not trying to be misleading at all.
UPDATE 3:
I asked Vaughn Vernon the following question:
Regarding collection-oriented repository, I have a question:
If I do Foo aFoo=fooRepository.getById(1); Foo anotherFoo=fooRepository.getById(1);
then is it guaranteed that both references are the same (aFoo==anotherFoo)?
And he answered the following:
That depends on the backing persistence mechanism, such as Hibernate/JPA. It seems it should if you are using the same session in both reads and both reads have the same transactional scope, but check with your ORM.

Simple Hibernate/JPA query returning proxy objects

I am using Hibernate 5 & Spring Data.
Inside my PartyDao, I have the following method:
#Query("from Party where id in :partyIDs")
List<PartyTO> loadByIDs(#Param("partyIDs") List<Long> partyIDs);
I am calling it like this:
partyList = partyDao.loadByIDs(userPartyIDsList));
but I am getting a list of Hibernate proxy objects (with all the fields set to null and a handler field of type org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer).
This makes no sense to me! Why is Hibernate not loading the objects FROM the query root I am specifying?
I changed it to:
#Query("select party from Party party where party.id in :partyIDs")
List<PartyTO> loadByIDs(#Param("partyIDs") List<Long> partyIDs);
to try to make it more explicit that that I want this object fetched, but it's still returning the proxy objects. Is there something I'm missing? I don't know how I would make it fetch itself.
EDIT:
The proxy object actually has an attribute called target, which has all the attributes set. Why are they not placed into the object itself?
I am not getting a "lazy initialization exception", but a NullPointerException inside a Comparator that is sorting the parties by name:
...
return o1.name.compareTo(o2.name);
The problem is your direct access to the name property of your object.
...
return o1.name.compareTo(o2.name);
Hibernate will always return proxy objects, and the serialization of some more complex structures might lead you to issues in the future including the lazy instantiation exceptions mentioned. However, the cause of your problem is direct access of a property, if you correctly utilize your getter functions within your comparators you will not have any other problem.
The proxy object is a runtime extension of your target class, it will have the same interface as the target class, but in true OOD fashion the internals are not visible or accessible. The only guarantee is the interface contract presented, and that is what you should be coding against regardless within your objects.
Change your comparator and other code to match the following, and you won't have this issue again.
...
return o1.getName().compareTo(o2.getName());
The value will be read into the main object by calling the property method instead of the attribute itself.
The Comparator return statement must be changed to:
return o1.getName().compareTo(o2.getName());

Spring JdbcTemplate: Getting Lists Not Mapped to an Object

I am using the NamedParameterJdbcTemplate in my Spring app.
I have a data bean object which will hold all my object attributes, "ApplicationVO". The first query, SELECT1_MAIN, populates the core attributes, others will be populated inside a For-loop for each result.
The first query is easy and returns a list of mapped objects (some fields are null). In the second one, I don't want to create separate data beans or any extra code. I want "anonymous" lists that I can step through and add values to my objects.
Some of the extra queries may return multiple fields. Is there an easy way to get anonymous lists without creating extra beans?
// Main Attributes
List<ApplicationVO> allEligibleApps =
jdbcTemplate.query(SELECT1_MAIN, paramMap, new BeanPropertyRowMapper(ApplicationVO.class));
// For each appl., fill out additional attributes
for (ApplicationVO appl: allEligibleApps)
{
List l = jdbcTemplate.query(SELECT2_INFO, paramMap2, BeanPropertyRowMapper(ApplicationVO.class));
appl.setInfoField1(l.get(0));
appl.setInfoField2(l.get(1));
}
NamedParameterJdbcTemplate.queryForList method should do what you ask for.

Java: Pattern for updating all equal objects (in the same context) that don't share the same reference

In my java application I am using equal objects multiple times at different places. That means the equals method returns true, when comparing theses objects. Now I want to update one object and make the changes to all objects that are equal. Do you know if there is a pattern for that?
My concrete use case is:
I am using JSF, JPA and CDI. A user is on web page that allows him to edit the detached entity EntityA. The page is sessionscoped. EntityA has two references to an EntityB (also detached). These objects can be same. Not the same reference, but they may be equal.
#Entity
public class EntityA {
#OneToOne()
private EntityB entity1;
#OneToOne();
private EntityB entity2;
}
The JSF view lets the uses select entity1 and entity2 from a selection list. It also shows some details of theses EntityBs and the user is allowed to edit entity1 and entity2 seperately. Everything works fine, except the user has choses the same (equal) EntityB for entity1 and entity2. Then, only the references to these objects are updated. Of course entity1 and entity2 are two different JPA entites, and are not the same reference. But I want to distribute the changes to all detached instances of EntityB. I have this situation hundreds of times in my application, so I dont want to take care about, which objects have to be updated in which situations. I need some solutation the does it for me automatically. One Idea was to keep all objects I use in this session in special list and every time a request was submitted and processed iterate over this map and change alle equal objects. But his sounds very dirty. Maybe there is a build in JPA function to make all equal objects the same reference. I dont know if this is possible. Do you have a solution for this? Thanks.
I'm going to abstract your problem out a bit here: if a change to one object requires changing a number of other objects, consider putting the field that you're changing in a separate object, and have all those objects reference it.
For example, if you have:
class MyClass {
String info;
int id;
}
and two instances of MyClass with the same 'id' should both be updated when the 'info' field changes then use this:
class myClass {
myInfoClass info;
int id
}
class myInfoClass {
String value;
}
and give all instances of myClass that are equal the same instances of myInfoClass. Changing myClass.info.value will effectively change all instances of myClass, because they all hold the same instance of myInfoClass.
Sorry if I've got the syntax slightly wrong, I jump between languages a lot.
I use this technique in a game I wrote recently where a switch activates a door- both the switch and door have a Circuit object that holds a boolean powered field. The doors 'isOpen()' method simply returned circuit.powered, and when the switch is activated I just call switch.circuit.powered = true, and the door is automatically considered 'open'. Previously, I had it searching the game's map for all doors with the same circuit id, and changing the powered field on each.
this is classic form handling logic
if the user clicks the save button manipulate the data in the database
reload the data every time you create the web page
you should not cache the data in the web session
if you need caching, activate it in the persistence layer (ex. hibernate cache)

Refreshing entity instance after using merge in hibernate?

am using hibernate merge method, to deal with detached instance from entity, and i thought that the return of this method will be a new fetched instance from database as hibernate saveOrUpdate method, but that wasn't the case, and i think it's logic as it's a detached instance, so is there a better way to return the new instance rather than using findById,
regards,
The merge method copies the state of the passed object to a persistent entity with the same identifier (that is either already associated with the session or will be loaded) and then return a reference to that persistent entity. The object passed as parameter is not attached to the session.
So unless I didn't understand the question, I think you should do something like this:
Foo mergedFoo = session.merge(foo);

Categories

Resources