I am responsible for a Java EE application that provides backend functionality to a number of clients. Some of the clients are also written in Java, so I have extracted my entities into a separate jar, which server and clients share.
The server uses JPA2 for persistence, JAX-RS for communication with clients and JAXB for serialisation to/from XML and JSON. As a result, the (shared) class files contain both JPA- and JAXB-annotations.
Obviously, the same object behaves differently on the server (where it is a managed JPA entity) and on a client (where it is a de-serialized POJO) - especially with regards to one-to-many relationships.
Question: Sometimes I'd like to have individual methodcalls behave differently depending on where they are executed. Can I solve this through inheritance, so that I don't have to manually maintain two implementations of the same classes?
Example:
A team has many players. A player has a name.
Requests are mapped to GET /team/<id> to get a Team, and GET /team/<id>/<playerName> to get a particular player for a team.
For marshalling and serialisation, the Team shall remain "flat" (don't include players). However, include their names in the serialisation so that the clients know which players they can retrieve in detail.
On the server side, I'd build it like this:
#Entity
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Team {
/* some other fields, belonging to the Team */
#OneToMany(fetch = FetchType.LAZY, mappedBy="team")
#XmlTransient // don't marshall the players
List<Player> players;
/* getters and setters as necessary */
#XmlElement
public List<String> getPlayerNames() {
List<String> names = new ArrayList<String>();
for (Player p : getPlayers()) {
names.add(p.getName());
}
return names;
}
}
On the client side, I'd map it to:
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Team {
/* some other fields, belonging to the Team */
List<String> playerNames;
public List<String> getPlayerNames() {
return playerNames;
}
public void setPlayerNames(List<String> playerNames) {
this.playerNames = playerNames;
}
/* getters and setters as necessary */
}
This way, the playernames get marshalled (through #XmlElement-annotated getPlayerNames()) on the server side. When the client receives it, it unmarshalls the list properly. Everybody is happy.
However, now I'd have to maintain two essentially identical classes, where only minor differences occur... What is the best way to do this properly?
Directly serializing entities and transmitting them over the wire may pose a problem, for example if you have circular references or if you like to include additional information which might be needed for deserialization, especially in JSON. Another issue might be detached entities (If you send them to the client, the entity manager loses control of the entities and you have to reattach them when they come back) or lazy load (you can't lazy load on the client). Therefore I would recommend to convert the entities into Data Transfer Objects before you transmit them over the wire. See Fowler's book Patterns of Enterprise Application Architecture (page 401, most of the chapter is available through Google Books) for details and motivation.
Using the same classes on the client and server might be problematic too because they behave differently and might diverge further in the future. You might restrict yourself to much by committing to an identical code base on the client and server or end up with a big mess.
Related
I would like to understand what's the benefits to create DTO objects when you already have POJO object (as Entity).
In my project I have both :
DTO classes are used to communicate between Web Service and the application
POJO entity classes (JPA) are used for communication between database and the application
If I look at a DTO object class (let's call it MyObjDTO) and the same class but POJO side (let's call it MyObjPOJO) there is no difference at all except MyObjPOJO as annotation due to the fact it's an #Entity.
So in fact, I got in my project 2 classes who look the same (same attributes, same methods) but for different puprose.
IMO, in this case the DTO class is useless and increase application complexity because all I do with DTO class I can do it with my POJO class and moreover, for a single type of object I have to maintain at least 2 classes (the DTO and POJO), for instance if I add an attribute I have to add this attribute in both classes.
I'm not an expert and I'm questionning about my thoughts; what do you think about it ?
This answer is a replica of what can be found on stack exchange. IMHO the OP should be closed for being posted in the wrong forum. It's currently also attracting opinionated answers, though not necessarily so, and isn't tied to java in any particular way.
DTO is a pattern and it is implementation (POJO/POCO) independent. DTO says, since each call to any remote interface is expensive, response to each call should bring as much data as possible. So, if multiple requests are required to bring data for a particular task, data to be brought can be combined in a DTO so that only one request can bring all the required data. Catalog of Patterns of Enterprise Application Architecture has more details.
DTO's are a fundamental concept, not outdated.
What is somewhat outdated is the notion of having DTOs that contain no logic at all, are used only for transmitting data and "mapped" from domain objects before transmission to the client, and there mapped to view models before passing them to the display layer. In simple applications, the domain objects can often be directly reused as DTOs and passed through directly to the display layer, so that there is only one unified data model. For more complex applications you don't want to expose the entire domain model to the client, so a mapping from domain models to DTOs is necessary. Having a separate view model that duplicates the data from the DTOs almost never makes sense.
However, the reason why this notion is outdated rather than just plain wrong is that some (mainly older) frameworks/technologies require it, as their domain and view models are not POJOS and instead tied directly to the framework.
Most notably, Entity Beans in J2EE prior to the EJB 3 standard were not POJOs and instead were proxy objects constructed by the app server - it was simply not possible to send them to the client, so you had no choice about haing a separate DTO layer - it was mandatory.
Although DTO is not an outdated pattern, it is often applied needlessly, which might make it appear outdated.
From Java guru Adam Bien:
The most misused pattern in the Java Enterprise community is the DTO. DTO was clearly defined as a solution for a distribution problem. DTO was meant to be a coarse-grained data container which efficiently transports data between processes (tiers). ~ Adam Bien
From Martin Fowler:
DTOs are called Data Transfer Objects because their whole purpose is to shift data in expensive remote calls. They are part of implementing a coarse grained interface which a remote interface needs for performance. Not just do you not need them in a local context, they are actually harmful both because a coarse-grained API is more difficult to use and because you have to do all the work moving data from your domain or data source layer into the DTOs. ~ Martin Fowler
Here is a Java EE specific example of a common but incorrect use of the DTO pattern. If you're unfamiliar with Java EE, you just need to know the MVC pattern: a "JSF ManagedBean" is a class used by the View, and a "JPA Entity" is the Model in the MVC pattern.
So, for example, say you have a JSF ManagedBean. A common question is whether the bean should hold a reference to a JPA Entity directly, or should it maintain a reference to some intermediary object which is later converted to an Entity. I have heard this intermediary object referred to as a DTO, but if your ManagedBeans and Entities are operating within the same JVM, then there is little benefit to using the DTO pattern.
Futhermore, consider Bean Validation annotations (again, if you're unfamiliar with Java EE, know that Bean Validation is an API for validating data). Your JPA Entities are likely annotated with #NotNull and #Size validations. If you're using a DTO, you'll want to repeat these validations in your DTO so that clients using your remote interface don't need to send a message to find out they've failed basic validation. Imagine all that extra work of copying Bean Validation annotations between your DTO and Entity, but if your View and Entities are operating within the same JVM, there is no need to take on this extra work: just use the Entities.
The Catalog of Patterns of Enterprise Application Architecture provides a concise explanation of DTOs, and here are more references I found illuminating:
HOW TO DEAL WITH J2EE AND DESIGN PATTERNS
How to use DTO in JSF + Spring + Hibernate
Pros and Cons of Data Transfer Objects Martin Fowler's description of DTO
Martin Fowler explains the
problem with DTOs. Apparently they were being misused as early
as 2004
Most of this comes down to Clean Architecture and a focus on separation of concerns
My biggest use-case for the entities is so i don't litter the DTO's with runtime variables or methods that i've added in for convenience (such as display names / values or post-calculated values)
If its a very simple entity then there isn't so much of a big deal about it, but if you're being extremely strict with Clean then there becomes a lot of redundant models (DTO, DBO, Entity)
Its really a preference in how much you want to dedicate to strict Clean architecture
https://medium.com/android-dev-hacks/detailed-guide-on-android-clean-architecture-9eab262a9011
There is an advantage, even if very small, to having a separation of layers in your architecture, and having objects "morph" as they travel through the layers. this decoupling allows you to replace any layer in your software with minimal change, just update the mapping of fields between 2 objects and your all set.
If the 2 objects have the same members...well, then that's what Apache Commons BeanUtils.copyProperties() is for ;)
Other people have already informed you of the benefits of DTO, here I will talk about how to solve the trouble of maintaining one more DTO version object.
I deveploy a library beanKnife to automatically generate a dto. It will create a new class base the original pojo. You can filter the inherited properties, modify existing properties or add new properties. All you need is just writing a configuration class, and the library will do the left things for you. The configuration support inheritance feature, so you can extract the common part to simpify the configuration even more.
Here is the example
#Entity
class Pojo1 {
private int a;
#OneToMany(mappedBy="b")
private List<Pojo2> b;
}
#Entity
class Pojo2 {
private String a;
#ManyToOne()
private Pojo1 b;
}
// Include all properties. By default, nothing is included.
// To change this behaviour, here use a base configuration and all other final configuration will inherit it.
#PropertiesIncludePattern(".*")
// By default, the generated class name is the original class name append with "View",
// This annotation change the behaviour. Now class Pojo1 will generate the class Pojo1Dto
#ViewGenNameMapper("${name}Dto")
class BaseConfiguration {
}
// generate Pojo1Dto, which has a pojo2 info list b instead of pojo2 list
#ViewOf(value = Pojo1.class)
class Pojo1DtoConfiguration extends BaseConfiguration {
private List<Pojo2Info> b;
}
// generate Pojo1Info, which exclude b
#ViewOf(value = Pojo1.class, genName="Pojo1Info", excludes = "b")
class Pojo1InfoConfiguration extends BaseConfiguration {}
// generate Pojo2Dto, which has a pojo1 info b instead of pojo1
#ViewOf(value = Pojo2.class)
class Pojo2DtoConfiguration extends BaseConfiguration {
private Pojo1Info b;
}
// generate Pojo2Info, which exclude b
#ViewOf(value = Pojo2.class, genName="Pojo2Info", excludes = "b")
class Pojo2InfoConfiguration extends BaseConfiguration {}
will generate
class Pojo1Dto {
private int a;
private List<Pojo2Info> b;
}
class Pojo1Info {
private int a;
}
class Pojo2Dto {
private String a;
private Pojo1Info b;
}
class Pojo2Info {
private String a;
}
Then use it like this
Pojo1 pojo1 = ...
Pojo1Dto pojo1Dto = Pojo1Dto.read(pojo1);
Pojo2 pojo2 = ...
Pojo2Dto pojo2Dto = Pojo2Dto.read(pojo2);
I am currently working on several solutions to redesign a web application based on a database that is shared between this application and other running services.
The actual application uses NodeJS, and basically processes data after having exctracted too much information from a table in the database. I think this is wrong, because we should only ask the database for the data we need, and limit processing on the server as these processes imply long loading time for end users.
So I thought I would build a Java API instead, that would use objects that can be easily used by the front part of the application, and use Hibernate or an equivalent component to extract necessary information from database.
But the problem is that the database over which I would build this API, while supposed to be relational (it's postgreSQL), is actually composed of tables that do not communicate between each other : there are no joins between tables, hence no cascade on modifiying related objects. Furthermore, the tables do not correspond directly to objects used in the application. They are more like "super objects" that would contain other sub-objects in a Java model.
Problem is, I cannot recreate a "cleaner" database as it is used by other services (which is probably why it is so weirdly organised, by the way). I should use it as it is, and map the redesigned application to it. I could be allowed to redesign some tables to make them "more relational", but this should have no implications for the other services. That would imply to drastically rewrite some SQL functions, and I am not sure that it is a very efficient solution. That being say, I am not very experienced on writing SQL functions, so maybe that could be a solution in the end.
So, to put it all in a nutshell, what could I do to build an object oriented model using Java, or any other technology that you could think of, to redesign properly the application, without throwing the database or modifying it drastically ?
Any suggestion or lead of research would be greatly appreciated. Also, please tell me if I am not being precise enough, and I will try to improve my question.
Use JPA to map your database records into entities.
This wiki page gives quite a few samples of advanced uses :
multiple tables for an entity :
#Entity
#Table(name="EMPLOYEE")
#SecondaryTable(name="EMP_DATA",
pkJoinColumns = #PrimaryKeyJoinColumn(name="EMP_ID", referencedColumnName="ID")
)
public class Employee {
...
#Column(name="YEAR_OF_SERV", table="EMP_DATA")
private int yearsOfService;
#OneToOne
#JoinColumn(name="MGR_ID", table="EMP_DATA", referencedColumnName="ID")
private Employee manager;
...
}
multiple kind of entities in single table (this sample is mine, there was no code on the wiki ; let's hope I didn't mess it up !) :
#Inheritance
#DiscriminatorColumn(name="DISCRIMINATING_COLUMN")
#Table(name="SOME_TABLE")
public class Generic { ... }
// only maps records from SOME_TABLE where DISCRIMINATING_COLUMN=SOME_VALUE
#Entity
#DiscriminatorValue("SOME_VALUE")
public class firstSpecificType { ... }
// only maps records from SOME_TABLE where DISCRIMINATING_COLUMN=OTHER_VALUE
#Entity
#DiscriminatorValue("OTHER_VALUE")
public class secondSpecificType { ... }
entities from proc calls :
// This stored procedure returns a result set and has one input parameter.
#NamedStoredProcedureQuery(
name = "ReadAddressById",
resultClasses = Address.class,
procedureName = "READ_ADDRESS",
parameters = {
#StoredProcedureParameter(mode=javax.persistence.ParameterMode.IN, name="P_ADDRESS_ID", type=Long.class)
}
)
#Entity
public class Address {
...
}
and many others.
I have inherited an application written in Java that uses JPA to access a database. The application uses an design pattern that I haven't come across before and I would really appricate some guidance on why this pattern is used. Like many applications, we have a front end, middleware, and back end database. The database is accessed via DAOs. Each method on the DAO loads a entity-DTO which is just a POJO with nothing but getters and setters and that entity-DTO is then passed into a entity-proper that has other methods that change the entity state. An example [class names changed to protect the inocent]
enum Gender
{
Male,
Female
}
class PersonDTO
{
private String mFirstName;
private String mLastName;
private Gender mGender;
...
String getFirstName() { return this.mFirstName; }
String setFirstName(String name) { this.mFirstName = name; }
// etc
}
class Person
{
PersonDTO mDTO;
Person(PersonDTO dto)
{
mDTO = dto;
}
String getFirstName() { return mDTO.getFirstName() }
String setFirstName(String name) { mDTO.setFirstName(name); }
// and so on
void marry( Person aNotherPerson )
{
if( this.getGender()==Gender.Female &&
aNotherPerson.getGender()==Gender.Male)
{
this.setLastName( aNotherPerson.getLastName() );
}
aNotherPerson.marry( this );
}
}
This is repeated across 30 or so entity classes, doubled to 60 with the DTOs, and I just cant get my head around why. I understand (bits) about seperation of converns and I also understand (bits) about the difference between an EAO based design to say an active record based design.
But does it really have to go this far? Should there always be at least one "DB" object that contains nothing but getters and setters that map to the DB fields?
Disclaimer: there are varying opinions on this subject and depending on your system's architecture you might not have a choice.
With that said... I've seen this pattern implemented before, not a huge fan of it, in my opinion is duplicates large amounts of code without adding any real value. It seems to be particularly popular in systems with XML APIs like SOAP where it might be difficult to map XML structure directly to your object structure. In your particular case it seems to be even worse because on top of duplicate getFirstName()/getLastName() methods, there is business logic (which belongs in the service layer) coded right into a pojo (which should be a simple data transfer object like the DTO). Why should the pojo know that only people of opposite sex can get married?
To help better understand why, can you explain where these DTOs come from? Is there a front-end submitting data to a controller which then converts it to a DTO, which is then used to populate your entity-proper with data?
It could also be that they are using this just to separate the JPA annotations from the rich domain object.
So I'm guessing that somebody didn't like having JPA annotations and the rich domain object behaviour in one class. Somebody could have also argued that the JPA annotation and the rich domain object should not be in the same layer (because the annotations mixes the concerns) so you would get this kind of separation if you won this argument.
Another place where you'd see this kind of thing happening is when you want to abstract similar annotations away from the rich domain objects (like jaxb annotations in web services for example).
So the intent might be that the DTO serves as sort of the serialization mechanism from code to the database, which is very similar to the intent mentioned here by martin fowler.
This doesn't appear to be a known pattern.
In general
it is common to maintain a separate object to represent the record in the database, referred to as domain object.
the CRUD operations on the object are part of a DAO class and other business operations would be part of a Manager class, but none of these classes store the domain object as a member variable, i.e. neither DAO nor Manager carry state. They are just processing elements working on domain objects passed in as parameters.
a DTO is used for communication between the front-end and back-end to render data from DB or to accept input from end-user
DTOs are transformed to Domain objects by Manager class, where validations and modifications are performed per business rules. Such domain objects are persisted in the DB using DAO class.
I have worked on one project where we have DTOs for the sole purpose of transferring information from front-end controller to some facade layer. Then facade layer is responsible for converting these DTOs to domain objects.
The idea behind this layering is to decouple front-end (view) from domain. Sometimes DTOs can contain multiple domain objects for aggregated view. But domain layer always presents clean, reusable, cacheable(if required) objects.
I have a problem regarding Java custom serialization. I have a graph of objects and want to configure where to stop when I serialize a root object from client to server.
Let's make it a bit concrete, clear by giving a sample scenario. I have Classes of type
Company
Employee (abstract)
Manager extends Employee
Secretary extends Employee
Analyst extends Employee
Project
Here are the relations:
Company(1)---(n)Employee
Manager(1)---(n)Project
Analyst(1)---(n)Project
Imagine, I'm on the client side and I want to create a new company, assign it 10 employees (new or some existing) and send this new company to the server. What I expect in this scenario is to serialize the company and all bounding employees to the server side, because I'll save the relations on the database. So far no problem, since the default Java serialization mechanism serializes the whole object graph, excluding the field which are static or transient.
My goal is about the following scenario. Imagine, I loaded a company and its 1000 employees from the server to the client side. Now I only want to rename the company's name (or some other field, that directly belongs to the company) and update this record. This time, I want to send only the company object to the server side and not the whole list of employees (I just update the name, the employees are in this use case irrelevant). My aim also includes the configurability of saying, transfer the company AND the employees but not the Project-Relations, you must stop there.
Do you know any possibility of achieving this in a generic way, without implementing the writeObject, readObject for every single Entity-Object? What would be your suggestions?
I would really appreciate your answers. I'm open to any ideas and am ready to answer your questions in case something is not clear.
You can make another class (a Data-Transfer-Object) where you have only the fields you want to transfer.
A way of custom serialization is implementing Externalizable
I would say the short answer to your question is no, such varied logic for serialization can't be easily implemented without writing the serialization yourself. That said an alternative might be to write several serializer/deserializer pairs (XML, JSON, whatever your favorite format, instead of standard yusing the built in serialization). and then to run your objects through those pairs sending some kind of meta-information preamble.
for example following your scenarios above you may have these pairs of (de)serialization mechanisms
(de)serializeCompany(Company c) - for the base company information
(de)serializeEmployee(Employee e) - for an employee's information
(de)serializeEmployee(Company c) - the base information of employees in a company
(de)serializeRelationships(Company c) - for the project relationships
For XML each of these can generate a dom tree, and then you place them all in a root node containing metainformation i.e.
<Company describesEmployees="true" describeRelationships="false">
[Elements from (de)serializeCompany]
[Elements from (de)serializeEmployee(Company c)]
</Company>
One potential "gotcha" with this approach is making sure you do the deserialization in the correct order depending on your model (i.e. make sure you deserialize the company first, then the employees, then the relationships). But this approach should afford you the ability to only write the "actual" serialization once, and then you can build your different transport models based on compositions of these pieces.
You could take an object swizzling approach where you send a "stub" object over the wire to your client.
Pros
The same object graph is logically available client-side without the overhead of serializing / deserializing unnecessary data.
Full / stub implementations can be swapped in as necessary without your client code having to change.
Cons
The overhead in calling getters which result in dynamically loading additional attributes via a call to the server is hidden from the client, which can be problematic if you do not control the client code; e.g. An unwitting user could be making an expensive call many times in a tight loop.
If you decide to cache data locally on the client-side you need to ensure it stays in-sync with the server.
Example
/**
* Lightweight company stub that only serializes the company name.
* The collection of employees is fetched on-demand and cached locally.
* The service responsible for returning employees must be "installed"
* client-side when the object is first deserialized.
*/
public class CompanyStub implements Company, Serializable {
private final String name;
private transient Set<Employee> employees;
private Service service;
public Service getService() {
return service;
}
public void setService(Service service) {
this.service = service;
}
public String getName() {
return name;
}
public Set<? extends Employee> getEmployees() {
if (employees == null) {
// Employees not loaded so load them now.
this.employees = server.getEmployeesForCompany(name);
}
return employees;
}
}
In one of my projects, I have an application that manages several clients (or customer if you prefer). For each of them, I have a dedicated schema on a database.
However, the application handles only one client at a time, i.e. the user must switch from one client to another in the application (at runtime, no restart of the application) in order to access the data from this new client.
How would you manage the connections, as well as the persistence layer, for this kind of project?
I want to use Hibernate for that. What are the points on which I must be really carefull when dealing with several database / schemas ?
Can Spring be of any help in this case?
If I am not clear enough, let me explain the situation with an example.
Imagine that my application can handle two clients: clientONE and clientTWO.
I already implemented a class that can provide me the database schema, user, password and connection String for a given client.
Each client have a list of debtors, but unfortunately, the DEBTOR table structure is not the same for clientONE and clientTWO.
Even the names of tables / columns are not the same...
So I can create one debtor class per client (I use Hibernate annotations):
#Entity
#Table(name = "T_DEBTOR_ONE")
...
public class ClientOneDebtor {
#Id
#Column(name = "ID_DEBTOR")
private String idDebtor;
...
}
and:
#Entity
#Table(name = "T_DEBTOR_TWO") // Table names are not the same among the different schemas...
...
public class ClientTwoDebtor {
#Id
#Column(name = "DEBTOR_ID") // It's just to show that the same information is stored in a column that has not the same name.
private String idDebtor;
...
}
Ideally, I will try to have a common Debtor class (here is an Abstract class, but I may use an Interface):
public abstract class AbstractDebtor {
public abstract String getIdDebtor();
...
}
#Entity
#Table(name = "T_DEBTOR_ONE")
...
public class ClientOneDebtor extends AbstractDebtor {
#Id
#Column(name = "ID_DEBTOR")
private String idDebtor;
...
}
#Entity
#Table(name = "T_DEBTOR_TWO")
...
public class ClientTwoDebtor extends AbstractDebtor {
#Id
#Column(name = "DEBTOR_ID") // It's just to show that the same information is stored in a column that has not the same name.
private String idDebtor;
...
}
This way, it will be easier for me to manipulate the Debtor objects in my DAO / Service layer, as I will not need to duplicate my DAO and Services for every client.
For example, the method from DAO to get the list of all Debtors will be public List<AbstractDebtor> getAllDebtors() { ... }.
So, how would I change the context when I change the client managed by my application?
In others words, how would I indicate to Hibernate (or Spring?) that I want to use the correct persistence objects (ClientOneDebtor or ClientTwoDebtor) regarding the client that is currently managed by my application?
If you think that I am going in the wrong direction, do not hesitate to share your ideas on how to solve this kind of problem...
Edit regarding the first answers:
The number of different schemas I will need to handle is around 15 - 20. In addition to that, I will only need to map only a little subset of their tables.
I also know that having one schema per client/customer is not the best solution for storing data. However, this architecture exist since 5 years, and we may move to only one schema during the next year (in the best case ;) ).
If only one at a time will every be required, it makes it much simpler. Simply create a SessionFactory per database. Avoid the HibernateUtils static SessionFactory instance approach and you won't have any problems.
A neat way to do this with Spring if you don't have too many databases (hundreds) is to instantiate a separate Spring ApplicationContext for each one that contains the SessionFactoryBean and DataSource configurations specially for that database.
You can use Spring mechanisms like PropertyOverrideConfigurer and a common parent ApplicationContext to factor out all the common stuff so that your many child ApplicationContexts are small and maintainable.
Then when a request comes in, just select the ApplicationContext you want to work with and start pulling beans out of it.
If you want to do it without Spring, you could also create multiple SessionFactory instances and store the "current" one in a static ThreadLocal.
Unfortunately, the Real World often does require multiple databases/schemas, especially when you have a vendor product whose database must be distinct from your corporate databases.
Making an arbitrary number of databases would be a mess, and for that, you really SHOULD consider a better form of data organization. But for a fixed (hopefully small) set of databases, just define them in the persistence configuration with a separate PersistenceUnit for each (which implies a separate EntityManager).
Using your illustrated inheritance scheme, you would assign the appropriate EntityManager to each derived class, assuming that the framework lets you.