Accessing Play Framework Model Outside of Play Framework - java

We have a large offline process that updates the model I designed inside of Play Framework. I think it makes sense to keep this code as a stand-alone project -- but I would like it to be able to use the JPA Model designed inside Play.
I'm wondering if there's a good way to handle this -- a way to reference the JPA Model independently of Play Framework (inside another vanilla Java project).
Another option is to create an API that the external process calls, which is what I've done so far, but it introduces a lot of unnecessary network latency.
Any pointers on how to accomplish this?

Passing around a Play specific JPA entity (ie. that extends Model) is probably not a good idea. You'd be introducing a dependency on the Play jars where they are not required.
As I see it you have two viable options:
Create the object as a POJO and use a Hibernate Xml Config (for Play
versions less than 2.0) to define the mapping to the database. You
can keep the pojo and the config entirely separate - ie. keep the
config in the classpath of your Play App.
Pass your object around in a serialized form eg. XML or JSON.

Related

Cross-framework Solutions for field Annotations

Does anyone have any strategies or examples of cross-framework libraries?
I am working on a project with an android app, a java server and a Java desktop client, which all use different frameworks. I need to refactor some core business logic into a separate library that can be used across all of these to ensure consistent behavior, but the field annotations are killing me.
The problem is that I am using Room in the Android app (which requires the #PrimaryKey annotation on the primary key field of a database entity) and JPA in the server and JavaFX client (which requires #Id).
Given this level of difficulty with the models, we initially copy-pasted the fields without annotations to the others when changing them. However, the business logic needs to make use of the models and accommodate each platform's specific ORM, Http client and Json serializer. (I know that it is technically possible to get Gson, Apache Http and Hibernate to run on all of these platforms, but actually doing any of these solutions created too many nightmares of its own)
As far as I can tell, there isn't a nice solution to this. Fortunately, the same #Inject is used in Dagger2 and CDI/CDI-SE so I have created some interfaces that each platform/framework will implement.
Does anybody have any examples or case studies I could look at which might help me arrive at a solution?
(I realize this question doesn't include any code samples, but it's more of a general programming strategy question.)
Disclaimer: I am the architect of JDX for Java and JDXA for Android ORMs.
You may consider using JDX for Java and JDXA for Android ORM frameworks to share the common object model, the core business logic code, and the data integration code across Java server, Java desktop, and Android platforms.
JDX and JDXA don't use annotations to define the mapping - instead they use an external text file to define the mapping specification based on a simple ORM grammar. So you may use the same mapping specification for your common object model across different platforms. Also, the APIs for both JDX and JDXA are simliar.
So, you just need to use the appropriate JDX(A) ORM library for your target platform and an appropriate JDBC driver for your target database without needing to change your object model or business logic.

can JPA eclipselink be mapped to REST service?

Nowadays typical JAVA application can expose some JPA entities via REST easily. In that case in short there is e.g. persistence.xml where driver, database, etc are defined to access the database and persistence unit easily can be used in the application.
I am looking for something opposite. I.e. if somebody saw the solution where persistence relays on REST API?
Background of my question is the following.
There is an app written in some ancient technology and there is quite complex logic behind. I would like to build new JEE JPA (Eclipselink if possible) based application which could (at least for some time) use that complex logic in order to find and read data. My idea was to implement REST interface on top of old application and let the new one use REST queries in order to deal with the data. Since logic is complex I would like to avoid duplicating it and maintaining 2 branches of code in different technologies until I am fully prepared to move all stuff into modern technology.
Do you think it is possible?
You can design your Data Access Layer and the rest of your new application so that it doesn't care how the data is stored (no "bad" dependencies).
You would then need to create separate versions of the DAL, where one would fetch the data from the legacy REST app and one would use JPA. This will make it possible to start out being dependent on the legacy app, and part by part build the JPA DAL to retrieve data from a database.

Hibernate objects and GWT-RPC

I want to transfer hibernate objects with GWT-RPC to the frontend. Of course i can not transfer the annotated class because the annotations can not be compiled to javascript. So i did the hibernate mapping purely in the ".hbm.xml". This worked fine for very simple objects. But as soon as i add more complex things like a oneToMany relationship realized with e.g. a set, the compiler complains about some serialization issues with the set (But the objects in the set are serializable as well).
I guess it does't work because hibernate creates some kind of special set that can not be interpreted by GWT?
Is there any way to get around this or do i need another approach to get my objects to the frontend?
Edit: It seems that my approach is not possible with RPC because hibernate changes the objects. (see answer from thanos). There is a newer approach from google to transfer objects to the the frontend: The request factory. It looks really good and i will try this now.
Edit2: Request factory works perfectly and is much more convenient than RPC!
This is a quote from GWT documentation. It says that hibernate changes the object from the original form in order to make it persistent.
What this means for GWT RPC is that by the time the object is ready to be transferred over the wire, it actually isn't the same object that the compiler thought was going to be transferred, so when trying to deserialize, the GWT RPC mechanism no longer knows what the type is and refuses to deserialize it.
Unfortunately the only way to implement the solution is by making DTOs and their appropriate converters.
Using Gilead is a cleaner approach (no need for all this DTO code), but DTOs are more ligtweight and thus produce less traffic through the wire.
Anyhow there is also Dozer, that will generate the DTOs for you so there will not be much need for yo to actually write the code.
Either way as mchq08 said the link he provided will solve many of questions.
I would also make another suggestion! Separate the projects. Create a new one as a model for your application and include the jar into the GWT. In this way your GWT project will be almost in its' entirety the GUI and the jar library can be re-used for other projects too.
When I created my RPC to Hibernate I used this example as a framework. I would recommend downloading their source code and reading the section called "Integration Strategies" since I felt the "Basic" section did not justify DTO. One thing this tutorial did not go over as well is the receiving and sending part from the web page(which converts to JS) so thats why I am recommending you downloading their source code and looking at how they send/receive each the DTOs.
Post the stack trace and some code that you believe will be useful to solving this error.
Google's GWT & Hibernate
Reading this (and the source code) can take some time but really helps understands their logic.
I used the next approatch: for each hibernate entity class I had client replica without any hibernate stuff. Also I had mechanism for copy data between client <-> server clases.
This was working, but I belive current GWT version should work with hibernate-annotated classes..
On a client project, I use Moo (which I wrote) to translate Hibernate-enhanced domain objects into DTOs relatively painlessly.

JAX-RS : Model and Best practices

I have a JAX-RS service (I use Jersey), and now I have to do the client. I was wondering how you guys use to deal with the model objects.
Do you put you model classes in a different jar in order to share it between the client and the server? Do you always use DTO or do you sometimes (always?) returns jpa entities.
The service I have to use (I haven't created it but I can modify it), often returns entities so I was wondering if it wasn't a bit weird if I externalize those classes.
What do you think? What are you use to do?
It depends on the complexity of the project and on the purpose you use JAX-RS in it:
for very simple projects I wouldn't create one more DTO layer whatsoever
for a project like yours that seems to use JAX-RS just to move data from a java client to a java server I wouldn't create one more layer either. That's because you are in charge at both ends (client and server) and because you reuse the same objects in both places (putting them in a separate jar and maven module is a good idea)
for projects that use JAX-RS to expose an API to external clients it's a good idea to separate the model from the API with DTOs so they are allowed to evolve independently. For example you don't always want to expose all the fields via an API or to break your clients when changing something in the model.
LATER EDIT
for a project that transfers only a subset of their model data fields to the client a DTO layer is useful for efficiency reasons

Transparently storing class state without exposing implementation

I have a model (MVC) class whose internal state (which basically contains of private int fields) I want to store.
The program is running on Android (for now) so I need to store the in a Bundle, but I'll be using the same class later in a desktop application where I'll have to store the state some other way, so I can't reference Bundle directly in my class.
So my question is: What is the best way to store (and retrieve) the state of a class without exposing it's implementation?
The best I could think of removing the private access modifier so that the fields become package accessible and create read/write helper classes in the same package, but that somehow seems wrong.
I'm not familiar with the persistence mechanisms on Android, but in general, it's a good idea to separate your persistence logic (i.e. the code that stores objects' state) from the domain objects that actually contain the data. That's the approach taken by JPA and virtually all modern object-relational mapping tools in Java, for example. So yes, referencing Bundle objects directly in your domain classes doesn't sound like the right strategy, especially if you plan to use the same classes in a non-Android environment, too.
My advice is to serialize the object state into XML, which is portable across environments. There are lots of open source tools available that help make this easy and don't require any special code in your domain classes. The two I'm most familiar with are JiBX and Castor. I don't know if either will work on Android, but even if Android has its own tools to transform objects to and from XML, you still might be able to use JiBX or Castor on the desktop side, since they can adapt to many different XML formats.
Once you have the data in XML form, you can persist it using whatever means is most appropriate on the target environment. On the desktop app, that probably means files in the user's home directory. On Android, I guess it would be bundles, but that's not my area of expertise. Good luck!
Take a look at the bridge pattern, as well: http://en.wikipedia.org/wiki/Bridge_pattern
As Rob said, you need to decouple the persistence from the data objects, so you can handle data uniformly and use a bridge to handle the persistence in different platforms.

Categories

Resources