Should my objects hold objects or object IDs? - java

For example should I be doing this
class MyObject {
private Long subObjectId; //such as this
private List<Long> subObjectIds; //or this
//bunch of other fields omitted
}
or
class MyObject {
private SubObject mySubObject; //such as this
private List<SubObject> mySubObjectList; //or this
//bunch of other fields omitted
}
Which one is considered the typical / better approach? If I want to populate something like MyObject from a database, I don't know if my objects should be holding onto IDs or actually populate the objects themselves.
Is it considered bad practice to use the second method but keep the objects null until I need to populate them (a sort of lazy population approach).
The advantage of the first method is that it's quick and easy to populate, but then if I ever wanted to get access to the actual object the ID points to, then I have to query the database and populate some separate SubObject that is decoupled from MyObject.
I hope my question is clear enough. Thank you.

If you are using some ORM like hibernate, then references are the way to go.
If you are not using an ORM, then ids are the way to go. If you start using references without an ORM, you are going to start running into situations where you need a reference but all you are receiving from the database is an id, and the only way to overcome these situations is by writing your own ORM. Don't re-invent that wheel.

Related

Generic - call actual methods of object passed in parameter

There are around 6 POJO classes (domain entities, DTO's, DMO's) all have almost same fields. To convert from one objec to another, I'm passing one object and calling its getters to set it in another object.
private UserTemp convertDmoToUserTempEntity(final UserDmo userDmo) {
final UserTemp userTemp = new UserTemp();
userTemp.setUsername(userDmo.getUsername());
userTemp.setPassword(userDmo.getPassword());
userTemp.setStatus(userDmo.getStatus());
return userTemp;
}
private UserDmo convertEntityToUserDmo(final UserTemp userTemp) {
final UserDmo userDmo = new UserDmo();
userDmo.setUserId(userTemp.getUserId());
userDmo.setUsername(userTemp.getUsername());
userDmo.setStatus(userTemp.getStatus());
return userDmo;
}
There are lots of these conversion like from one entity to another, DTO to DMO, DMO To DTO etc. I believe the better way to handle this would be Generics, passing source object and destination object.
public static <E, T> T convert(E e, T t) {
//call getter of source object to set it in destination object.
return t;
}
UserConverterImpl.convertFromTempToUser(userTemp, user);
I need help in this. When I pass object in parameter, I need a way its methods. Is there any better way to achieve this?
You could try to use a framework for this. In the past I have used Dozer to do this.
In following post, other frameworks are mentioned as well
any tool for java object to object mapping?.
(some advice: When mapping JPA entity objects, watch out for lazy fields being automatically mapped by the frameworks)
Perhaps you don't want/cannot use a separate framework for whatever reason.
Since you seem to have a strict layering, you will probably have mappers for each layer. Then I would go for a separate mapping for each object. This way you can easily work out mapping from username to userId etc. The chances that all objects in the layers have exactly the same names for their methods are not that high, and likely to change anyway.
Ended up using BeanUtils of Spring.
BeanUtils.copyProperties(Object source, Object target)

What is the best way to deal with #OneToOne general type

What is the best way to deal with something like (I know that this code would not work as the Object is not specified, It is just example):
#OneToOne
private Object _reference;
where the variable _reference can be from different kind of documents (from different database table). One of the ideas I have is to keep:
private int _docId;
private String _docTableReferenceName;
and then use reflection to get proper object, it would look something like:
session.get(Class.forName(_docTableReferenceName), _docId);
But this way has one drawback. It does not guarantee data consistency (as I need to remove the object when the _reference is removed). Sure I can work around with this by adding functions removeDocA, removeDocB but I wonder if maybe someone know more sophisticated way.
I need to have the fast way to reference object in both sites (without searching in all table rows).

Object Relational mapping and performance

I am currently working on a product that works with Hibernate (HQL) and another one that works with JPQL. As much as I like the concept of the mapping from a relational structure (database) to an object (Java class), I am not convinced of the performance.
EXAMPLE:
Java:
public class Person{
private String name;
private int age;
private char sex;
private List<Person> children;
//...
}
I want to get attribute age of a certain Person. A person with 10 children (he has been very busy). With Hibernate or JPQL you would retrieve the person as an object.
HQL:
SELECT p
FROM my.package.Person as p
WHERE p.name = 'Hazaart'
Not only will I be retrieving the other attributes of the person that I don't need, it will also retrieve all the children of that person and their attributes. And they might have children as well and so on... This would mean more tables would be accessed on database level than needed.
Conclusion:
I understand the advantages of Object Relational Mapping. However it would seem that in a lot of cases you will not need every attribute of a certain object. Especially in a complex system. It would seem like the advantages do not nearly justify the performance loss. I've always learned performance should be the main concern.
Can anyone please share their opinion? Maybe I am looking at it the wrong way, maybe I am using it the wrong way...
I'm not familiar with JPQL, but if you set up Hiernate correctly, it will not automatically fetch the children. Instead it will return a proxy list, which will fetch the missing data transparently if it is accessed.
This will also work with simple references to other persistent objects. Hibernate will create a proxy object, containing only the ID, and load the actual data only if it is accessed. ("lazy loading")
This of couse has some limitations (like persistent class hierarchies), but overall works pretty good.
BTW, you should use List<Person> to reference the children. I'm not sure that Hibernate can use a proxy List if you specify a specific implementation.
Update:
In the example above, Hibernate will load the attributes name, age and sex, and will create a List<Person> proxy object that initially contains no data.
Once the application accesses calls any method of the List that requires knowledge of the data, like childen.size() or iterates over the list, the proxy will call Hibernate to read the children objects and populate the List. The cildren objects, being instances of Person, will also contain a proxy List<Person> of their children.
There are some optimizations hibernate might perform in the background, like loading the children for other Person objects at the same time that might be in this session, since it is querying the database anyways. But whether this is done, and to what extend, is configurable per attribute.
You can also tell hibernate to never use lazy-loading for certain references or classes, if you are sure you'll need them later, or if you continue to use the persistent oject once the session is closed.
Be aware that lazy loading will of course fail if the session is no longer active. If for example you load a Person oject, don't access the children List, and close the session, a call to children.size() for example will fail.
IIRC the hibernate session class has method to populate all not-yet-loaded references in a persistent oject, if needed.
Best read the hibernate documentation on how to configure all this.

Persisting a Map<String,String> in ORMLite without resorting to DataType.SERIALIZABLE?

I've got a relatively simple class that is primarily backed by a Map<String,String>. I'd like to persist this class and be able search within the keys within the map. Based on this Stack Overflow question I get the feeling that Maps can only be persisted as a serialized blob.
I also see on the ORMLite website the following:
public class Account {
…
#ForeignCollectionField(eager = false)
ForeignCollection<Order> orders;
…
}
In the above example, the #ForeignCollectionField annotation marks
that the orders field is a collection of the orders that match the
account. The field type of orders must be either ForeignCollection
or Collection<T> - no other collections are supported. The
#ForeignCollectionField annotation supports the following fields:
Based on the above I get the impression that what I want isn't possible, but I thought I'd check here to be sure. I have it persisted in Hibernate, but I'd rather use something lighter like ORMLite!
One pretty easy solution is to have the getters and setters work with a JSONObject behind the scenes, and putting that object as a String in the database.
But then again, JSON isn't part of java-out-of-the-box so this may feel unneccesary if you're not using it anyway.
Yeah, there is no way in ORMLite to persist a Map. Keeping with the KISS principle, only the simple Collection class is supported. Set and Map have a lot more interface weight to them and will probably never be supported.
I don't have any super great work arounds for you. You could obviously use ForeignCollection and then have a local Map field that you create when you need to access the collection that way. Maybe an addOrder() method that would add it to the ForeignCollection and the Map.

Best Practice for Spring MVC form-backing object tree initialization

If I have a form-backing object that has a complicated object tree -- say a Person that has a Contact Info object that has an Address object that has a bunch of Strings -- it seems that the object needs to be fully populated with component objects before I can bind to it. So if I'm creating a new Person, I need to make sure it has all the component objects populated off the bat, and if I'm retrieving a Person from the database, I need to make sure that any objects that aren't populated from the database get populated with empty objects.
First question, of course -- am I correct in my assumptions above? It does seem that if I try to bind to person.contactInfo.homeAddress.street and there is no ContactInfo, I get a null pointer exception.
Second, what's the best way to initialize my object. I can think of a couple of approaches. One is to initialize all member objects at declaration:
public class Person {
String name;
ContactInfo contactInfo = new ContactInfo();
//getters, setters, etc.
}
public class ContactInfo {
String phone;
Address homeAddress = new Address();
}
and so forth.
Another approach is to have a PersonFactory that initializes everything (or to have a factory method Person.getInstance that initializes everything).
In the case of retrieving a Person from the database, the first approach will solve the issue (i.e. if this particular person doesn't have an address in the database, the object will still have an Address), but this will mean creating each object twice. Not sure how to handle this otherwise, except to make the DAO explicitly populate everything even if nothing has been retrieved from the database. Or to give the factory a method to go through the object and "fill in" anything that's missing.
Suggestions?
Call it overkill if you like, but what we actually ended up doing was to create a generic factory that will take any object and use reflection to (recursively) find all the null properties and instantiate an object of the correct type. I did this using Apache Commons BeanUtils.
This way you can take an object that you may have gotten from various sources (a DAO, deserialization from XML, whatever), pass it through this factory, and use it as a form-backing object without worrying that something you need for binding may be null.
Admittedly, this means instantiating properties that we may not need for a given form, but in our case that doesn't typically apply.
I would generally make sure objects are fully initialized - it makes using the object that much simplier and avoids you scattering null checks throughout your code.
In the case you give here I'd probably put the initialization in the getter so the child object is only instantiated when it's actually going to be used, ie: when the getter is called and then only if it's null.
In terms of loading from the database with one-to-one relationships I'd normally do the join and load the lot. The performance impact is typically minimal but you should be aware that there may be one.
When it comes to one-to-many relationships I normally go for lazy loading. Hibernate will take of this for you, but if you're rolling your own then you just need a custom implementation of List that calls the appropriate DAO when any of the methods relating to its contents are called.
The one exception to this behavior with one-to-many relationships is when you've got a list of parent objects that you intend to iterate over and for each parent you want to iterate over its children. Obviously the performance would suck because you'd be making a n + 1 calls to the DB when you could actually do it with 2 calls.
I guess you are talking about something like < form:input path="person.contactInfo.homeAddress.street"/> ?
Not clear for me but assuming i'm right :) :
1) Yes, When you write person.contactInfo.homeAddress.street , read person.getContactInfo().getHomeAddress().getStreet(). If ContactInfo or HomeAddress or Street objects are null, invocation of one of their method raises a NullPointException.
2)I usually initializes member objects at declaration, just like in code snippet. Don't see the benefit of factory class to do the job if initialization values are inconditionnal.
I don't clearly see the problem where you are forced to create a Person twice... but i may be tired ;)
I've gone with the Factory method approach (not a fan of using a seperate class for it, to me it makes more sense to have it in a static method so it's all in one place). I have something like -
public static Person getInstanceForContactInfoForm() {
ContactInfo contactInfo = ContactInfo.getInstanceForContactInfoForm();
Person person = new Person(contactInfo);
// set whatever other properties you need for Person
// just enough to 1-render the form and 2-avoid any exceptions
return person;
}
If I'm loading the Person from the database, I have a method in the Person class called something like "initalizeForContactInfoForm" or something. After loading the Person from the database, I'll call this method in the Service layer in the method that is called by the Spring MVC method which returns the Form Backing Object.
I don't think this is a really a convention, it's just an approach I cooked up on my own. I don't really see what any drawbacks are so if somebody disagrees please let me know...

Categories