I am developing a server for a web-client. Basically it's just a simple CMS to modify some data. My problem is that I never had a project like this where I have to take care about the server and the client and of course everything that happens between those two.
I've started to implement a database with Hibernate which is a great tool but it has its learning curve - I can tell. However, the client is also written in Java. Here I am using GWT. The thing now is that my database keeps growing and is getting more and more complex and I am not quite sure if the way I am doing it is sane.
To keep it simple assume we just have e.g. a Store that has collections of Item, those again have an ItemDescription and those descriptions e.g. do have foreign keys to Language in order to provide different translations. So far so good.
What am I sending to the client? What I did for now is I built POJO objects that basically are mirror images of the Hibernate entities:
public class LanguageDTO implements Serializable {
private static final long serialVersionUID = 1991918538222888435L;
private Long id;
private String name;
// Getter/setter
}
and with Hibernate:
@Entity
public class Language implements Serializable {
private static final long serialVersionUID = 3968717758435500381L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="ID")
private Long id;
@NotNull
@Column(name="LANGUAGE_CODE", length=2,unique=true)
private String languageCode;
@NotNull
@Column(name="LANGUAGE_NAME", length=50,unique=true)
private String languageName;
public Language() { }
// Getter/setter
}
I have done the same to Store, Item, ItemDescription etc. and I am sending the actual IDs from the database to the client and back to the server for persistence routines.
But I didn't stop there. I have also "mirrored" the relations between the POJO objects. That means I have basically almost an exact copy of the database on the client side (of course only the data that corresponds to a logged in user).
Is it a good idea to do that?
I personally like this because to me nothing really changes. Since I know the database I have no troubles finding the stuff I need on the client. Another thing that I like is that I e.g. have a map Map<Long, ItemDescription> on the client side that mirrors the relation Language.id and ItemDescription. This is convenient since The client can work with different languages right away.
But here comes the thing that is starting to make me a little wonder if I should do it like that. On the server I have to util classes ConvertToDTO and ConvertToEntity which have a lot of functions like that:
public static Item convertItem(Store store, ItemDTO itemDto) {
Item item = null;
Session session = HibernateSession.openSession();
session.beginTransaction();
if(itemDto != null) {
if(itemDto.getItemId() != null) {
item = (Item)session.get(Item.class, itemDto.getItemId());
if( item != null ) {
session.close();
return new Item(store, itemDto.getAvailable());
}
}
}
item = new Item(store, false, false);
session.save(item);
session.getTransaction().commit();
session.close();
return item;
}
which basically converts a DTO POJO into a Entity class. These static functions are using each other:
public static Tool convertTool(Store store, Language language, ToolDTO toolDto) {
ItemDTO itemDto = toolDto.getItem();
Item item = ConvertToEntity.convertItem(store, itemDto);
Tool tool = new Tool(store, item);
toolDto.getItemDescription(language.getId());
// ...
return tool;
}
which is the downside of the way I decided to do it. I have to have the complete entity data to restore an entity object and e.g. if the user created a new Item I have to check this:
if(itemDto != null) {
if(itemDto.getItemId() != null) {
item = (Item)session.get(Item.class, itemDto.getItemId());
if( item != null ) {
session.close();
return new Item(store, itemDto.getAvailable());
}
}
}
item = new Item(store, false);
session.save(item);
session.getTransaction().commit();
session.close();
and I am not sure if I should do that either like this.
I have the feeling that I'm doing a few things much more complicated than I should. Another question that arises is "how much" data should I send to the client and how to keep track on changes the user is doing to the DTO objects. After all I have to persist the returning DTO objects and in order to do that I have to check and validate everything field by field.