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.