0

So, I have project in which several WebServices will be created (REST). For the sake of simplicity, Lets name them A, B, and C. A and B handle different tasks, but both of them consume C, which is the only one with Database access.

A - Manages X Tasks

B - Manages Y Tasks

C - Manages Database Interaction

They all are packaged into WAR and deployet to Tomcat Servers. At the moment, they will coexist in the same server, but this may change down the road.

I'm facing an issue where, classess on C are annotated as per JPA standards.

Sample:

@Entity
@Table(name = "EVENT")
@NamedStoredProcedureQuery(...)
public class Event implements Serializable {

    // EVENTID NUMBER
    @Id
    @Column(name = "EVENTID")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "eventIdSequence")
    @SequenceGenerator(sequenceName = "EVENTID_SEQ", initialValue = 1, allocationSize = 1, name = "eventIdSequence")
    Long eventId;

    // TIMESTAMP DATE
    @Column(name = "TIMESTAMP")
    Date timeStamp;

    ... some other variables ...
    ... getter and setters ...

}

but I use the exact same class, without annotations, on A & B.

Sample:

public class Event implements Serializable {

    Long eventId;
    Date timeStamp;

    ... some other variables ...
    ... getter and setters ...

}

I know I should refactor in such a way that I don't need to create each class on each project I make. So, here is my issue:

I can create a library D, which only contains these models, which A and B can simply import. However, I cannot do the same on C, because C uses annotations for database interaction.

Which should be the best approach to take, tackling this issue? Can my JPA @Entity simply extend from data class? How would column mapping go about then? Can a project without JPA dependency use JPA entity classes as simple data classes?

Any help on how to take this approach is appreciated! (if it's of any relevance, I'm currently using Spring Boot)

0

If you are going introduce library which would be used in different projects then you have to segregate changes in DB and your library. On approach is to create and maintain two classes/data models: one JPA-related and another without any JPA references. The only way they are linked is constructors like Event(EventDb entity). Without inheritance, without composition.

No doubt, it cause more work when you add some property but it's price for flexibility. When you see DB field which don't needed both for service A and service B you would be happy about de-coupling DB and business layer. The same when you have to add field to Event which doesn't needed in DB. And no doubts, once you will meet such requirements.

I worked on couple projects which use such way: get data from DB, then put desired fields to POJO, then send that POJO to frond-end/another service. If you go that way, all you need is to create in library D appropriate adaptors/builders.
Also, I suppose there are tools which could generate such classes automatically but I can't remember any right now.

| improve this answer | |
0

I know I should refactor in such a way that I don't need to create each class on each project I make

Not really. Event (as an entity) and Event (as a bean) looks the same but they are indeed different models addressing different needs. The first is intended to model the persistence data model, the second (I assume) is a representation of the first, allocated in another system. Just happens that you have modelled the persistence and its representation alike if not the same. But in essence, both have different reasons to change hence responsibility.

On the other hand, they are mere data structures with no important knowledge to keep centralized in a single component/model for reuse or extension. So if you are concerned about DRY, don't be it.

I can create a library D, which only contains these models, which A and B can simply import.

It's annoying having the same mappings (POJOs or DTOs) repeated in different applications but the coupling generated by D doesn't make a big deal improvement. The SDLC of C will condition D hence the SLDC of A and B. Some of the changes in D might cause a chain effect involving changes in several applications. Something you could mitigate implementing a different integration pattern.

That said if you still want to go down this way...

However, I cannot do the same on C, because C uses annotations for database interaction.

Yes, you can. Jut get rid of the annotations. Configure persistence and mappings by XML. It's likely you will have to override some Spring bean which use to be autogenerated. As for instance the EntityManager or the EntityManagerFactoryBean.

Note that this way, you can package the XML files and the mapping classes in the same library with no side effect because Spring doesn't load persistence.xml files by default. This is something you have to do manually only in C.

Related links

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.