How can i seperate calculated values from auto generated JPA entities? - java

I created my JPA entities via reverse engineering in netbeans and i also added some calculated values to my entities like; i have name and surname fields in the users table and i created a method in user entity like
public String getDisplayName()
{
return name + " " + surname;
}
And i have several of this and in addition i've overridden some superclass methods like compareTo(), toString()
What i want to do is to seperate these methods so when i regenerate the entities i'll not have to add these methods manually again and again.
As i know, you can not seperate a class to multiple files in java.
I tried inheritance as well but i'm not sure what is going to be the best practice.
Regards.

Basically, if you want to share some code between 2 classes, there are only 2 possibilities:
Inheritance, where the shared code is delegated to an abstract class and the concrete implementations extend it. If you use it in JPA, you have to be aware that data bases (generally) do not support such approach and you have to design the mapping (https://thorben-janssen.com/complete-guide-inheritance-strategies-jpa-hibernate/).
Composition, where the shared code is encapsulated in a separate class used as a field type in concrete implementation.
Example of the latter:
#Entity
public class PersonalData {
private String name;
private String surname;
public String getDisplayName() {
return name + " " + surname;
}
}
#Entity
public class User {
private PersonalData data;
}
Additionally, to avoid boilerplate code creation, you can use Lombok: https://projectlombok.org/

Related

Does it make sense for a Student class to have a static method getAllStudents()?

I'm practicing with MVC, DAO and other design patterns for a Java project.
Let's say I have a PageController that interacts with a Student class Model.
public class Student {
private int id;
private String name;
public Student(int id, String name) {
this.id = id;
this.name = name;
}
//Getters and setters blabla
}
and then I have obviously a StudentDAO interface and StudentDAOImpl that executes SQL queries and stuff.
Let's say PageController needs to retrieve a list of all Students (to list them on its page), obviously I have an SQL query to retrieve a List of Students, implemented with a Java method in StudentDAOImpl.
Where should I instantiate studentDao (instance of StudentDAOImpl) though?
Can I simply create a static method in Student that retrieves all the Students? This static method would simply instantiate studentDAO and execute its getAllStudents method to retrieve all the students.
Or I can simply instantiate studentDao in PageController and do all the stuff from there?
In the main case, I think you could use this guide
DAO isn't a model, so you can add a method. I suppose that PageController would have a StudentRepository(StudentDAO) where will be a method getAll.
The structure mostly depends on the logic of your application.
Adding getAllStudents (database access method) to the Student class is, in fact, related to a design pattern called Active Record
Well, it's usually an anti-pattern for some people. Take a look at this article for detailed explanation.
On the other hand, you mentioned that you are using a DAO, which is a different design pattern for the same use case. I recommend you decide on a single option only.
If you are relying on DAO, everything related to data-access goes there. The model class must keep data only. However, be aware that this will lead you to an Anemic Domain Model, which has, in turn, its own drawbacks.
My preferred approach is DDD, it balances the responsibility of the data-related classes in a more consistent way.
Regarding where instantiate your DAO, the rule of thumb is: don't do it. Use Dependency Injection instead.
It's better because it leverages testability and maintainability of your code.

Is there an efficient way to distribute beans without annotations?

I have some beans that I annotated with JPA to handle persistence mapping.
Here is an example:
import javax.persistence.Id;
public class User{
#Id
private String id;
public String getId(){
return id;
}
public void setId(String id){
this.id = id;
}
}
Now I want to use this class in another project where I don't need a dependency on javax.persistence, so I'd rather not include it just for such classes.
So I was thinking of splitting this bean in two classes: one with just fields and accessors and a subclass with JPA annotations on accessors. Like:
public class User{
private String id;
public String getId(){
return id;
}
public void setId(String id){
this.id = id;
}
}
and
import javax.persistence.Id;
public class UserEntity extends User{
#Override
#Id
public String getId(){
return super.getId();
}
}
Unfortunately it seems that putting JPA annotations on accessors is a discouraged practice in most cases and I second that.
Can you suggest any cleaner solutions?
This may not be helpful if you absolutely have to use the annotation-based mapping for JPA, but if you are open to it you could configure your mappings using xml and not include the xml mapping file in the jar you use to share the User class with other projects.
See example here:
Persisting Entity Classes using XML in JPA
If you insist on using annotations to define your entity mappings, then your entity classes cannot avoid being dependent on JPA. If you must present non-JPA-dependent classes representing the same data, and if you want to be able to handle the different representations polymorphically, then your options are limited:
the annotated class may extend the non-annotated one, or
the annotated and non-annotated classes may extend a common superclass, or
the annotated and non-annotated classes may implement a common interface.
In any of those cases, the entity class can provide its own, annotated, member variables for the entity properties, but in all cases, doing so means the two classes provide separate storage for the entity properties. That's a bit wasteful in the first alternative and possibly in the second, but it's the only way you can annotate the member variables without tying the whole hierarchy to JPA.
If you want to go in this general direction then I'd recommend using interfaces instead of class inheritance, whether you annotate member variables or accessor methods. Using interfaces for polymorphism better models the reality you describe (some Users are entities but others are not), it does not interfere with any inheritance hierarchy you may want, and if you annotate member variables then it avoids duplicative storage .

GWT generate class methods

In my project I have a series of Models which basically just contain data, and have getters and setters for that data (which has to match an API). I am trying to use GWT generators to generate the getters and setters (because they have some logic in them for setting default values and I don't want to have this typed out all the time.
For example, MyBusinessModel.java:
public class MyBusinessModel extends AbstractBusinessModel {
private Integer uid;
private String name;
//... and so on
}
I then create a public abstract class AbstractBusinessModel which has some implemented base methods. I had created a generator for this, AbstractBusinessModelGenerator extends Generator, which automatically creates all the getters and setters, but I keep getting errors about MyBusinessModel not being able to be a superinterface of MyBusinessModelImpl (the generated class) because it's not an interface.
Is there a way for me to generate classes like this (I can't make MyBusinessModel an interface because I need it to have private properties), or can I only generate interfaces (which become classes)?
The answer is to use setSuperClass on the ClassSourceFileComposerFactory instead of addImplementedInterface. I didn't realise that this existed. Now I do.

Read ENUM and its fields from a database (JPA)

I have a model object that's in fact an enum with fields and getters:
#Entity
public enum Type {
TYPE1, TYPE2, TYPE3, TYPE4;
#Column
private Long id;
#Column
private String name;
...
public String getName() {
return this.name;
}
...
}
It compiles and runs fine. However, if I call a getter method, it returns null (it doesn't load any values stored in the database). Is this the standard behavior? Is there a way to make JPA load them?
I'd say there is some misconception in this aproach:
Entities represent objects that can be stored in the database. In this case, the database (or any other persistent store) defines which instances are available.
Enums represent a fixed set of constants that are defined in source code. Thus the class itself defines which constants are available. In addition, it's generally bad practice to change the values of an enum, i.e. the name or id in your case.
You see that they are two quite different concepts which should be treated differently.
To store enums in entities (where the enum is a field of that entity), you could either use #Enumerated and store the name or ordinal of the enum, or (what we do more often) store one of the fields (we mostly use the id) and provide conversion methods.
If you want to store configurable "constants" in the database you might try and use plain entities for that, make the constructor private (Hibernate and other JPA providers should be able to deal with that) and provide an alternative implementation of the Enum class (you can't use the enum keyword though).
Have you looked into the #Enumerated annotation? I haven't ever tried to use it within an enum itself, however it works quit well binding a class property to an enum.
enum Type{TYPE1, TYPE2}
#Column(name="type")
#Enumerated(EnumType.STRING)
public Type getType(){return type;}
public void setType(Type t){type = t;}
If JPA cannot be made to handle this, you could add a public Type valueOf(long id) method to your enum class which you use as a factory to instantiate enum instances representing the values in your legacy table.

How to "slice" a POJO

I'm borrowing the "slice" meaning from C++.
Let's say I hava a simple POJO that's persisted via Hibernate:
class Person {
private long id;
private String name;
...
// getters and setters here
...
}
Now, when I retrieve an object from the database I know it was "instrumented" by Hibernate (its real class is a Person-derived generated automatically). I want to convert it back to a "plain" person object. Tnat would be used, for instance, to submit the object to XStream and have the result containing only what Person contains.
I could do it by defining a copy constructor, but I don't want to have the hassle of having to write copy constructors for every ORM class (not to mention the violation of DRY principle).
So I was wondering if
a) is there already a Java lib that does it?
b) If not, would it be practical to write one using reflection?
In case of (b), any recomendations/guidelines/code skeletons would be appreciated.
The bean mapping library Dozer does an excellent job of this and is dead simple to use.
Simply map an instance of the bean returned by Hibernate to it's own class:
Person person = session.load(...);
BeanMapper mapper = ...;
Person cleanPerson = mapper.map(person, Person.class);
voila, no more Hibernate proxies or lazy-loaded collections!
The class org.apache.commons.beanutils.BeanUtilsBean probably does almost everything you want. The copyProperties method will go through calling the getters on your Entity and looking for setters with a matching property name on a target object you provide. You may need to handle some nested entities, depending on what kind of behavior you want and if/how you map relationships.
If you need to get more sophisticated you can register a Converter for turning your nested entity types into something else as well.
There is an interesting discussion about your problem here
http://www.mojavelinux.com/blog/archives/2006/06/hibernate_get_out_of_my_pojo/
Several solutions are proposed in the comments. In particular
http://code.google.com/p/entity-pruner/
http://www.anzaan.com/2010/06/serializing-cglib-enhanced-proxy-into-json-using-xstream/
I personally am huge on layer separation, and would argue that classes that you want to serialize across the wire or to XML should actually be separate from your data access layer classes, which would also solve the problem.
class SerializablePerson
{
... fields you care about ...
SerializablePerson(Person person)
{
... set only what you care about ...
}
}
You could have a Person class without persistence information wrapped by a persistent counterpart, like this:
public class Person implements Serializable
{
private String name;
// others.
}
public class PersistentPerson
{
private Long id;
private Person data; //
public Person getPerson() { return this.data; }
}
I'm not sure the design is worth it. The dual model makes me throw up in my mouth a little, just while writing this example.
The larger question is: Why do you think this is necessary? IF there's no good way to tell XStream to not include the id when serializing, I'd say it'd be better to write your own javax.xml.bind.Marshaller and javax.xml.bind.Unmarshaller to get what you want.
There are better ways to solve this problem than bastardizing your entire design.

Categories