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.
Related
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.
I am trying to divide a monolithic system into microservices using Spring Boot. The problem I encountered is that while each microservice should normally have classes that implement the service functionality, I need to receive and deal with objects that encapsulate many classes that are related to other microservices. For example, the code below is part of microservice1, which provides student information:
class Microservice1{
int id;
String name;
int grade;
Record record;
}
Notice now that the Record object is of a class that belongs to another microservice, which is microservice2, which provide student record as the following:
class Microservice2{
List<int> marks;
Behaviour behaviour;
}
Now behaviour is also another object whose class belongs to another microservice 3, and so on.
My question is: How do I get rid of the issue of having to include all these classes in microservice 1 because microservice1 needs to deal with them while providing the service? The problem is serious because I have many encapsulated classes inside each other, and I would need to include most of the monolithic system classes in one microservice.
As far as i can see, you are making your microservices way too granular. You'll have a lot of trouble implementing that way.
IMHO, if a Record is related to a Student AND belongs to the same business context, they belong to the same microservice.
As David said in the comments, Bounded Contexts concept can (really) help you.
Anyway, imagine that you want to follow in that line which you're proposing. If a Record belongs to Microservice B and you have to reference it by composition somewhere in Microservice A, the only thing you'll need, is it's primary key. Not the whole object.
Would be something like this:
Microservice A:
Student.java
public class Student {
private Integer id;
private String name;
private Integer grade;
private Integer recordId;
// getters and setters omitted for brevity
}
Microservice B:
Record.java
public class Record {
private Integer recordId;
private List<Integer> marks;
private Integer behaviourId;
// getters and setters omitted for brevity
}
And so on..
But as I said, maybe this is not the best approach.
See here a good article on Bounded Context.
I believe you are clear on the bounded context aspect. Practically, it will be hard to review each and every class for having a relationship with each other as you have shown in your sample. I would suggest to use a tool that can visually show you the dependency. Then you after placing them into their bounded context you can begin the key mapping, to fetch data from other microservice(s).
I am just starting to apply RealmDB in my application. I have one question regarding nesting objects.
I have previous experience working with Entity Framework. There is one useful feature available in Entity Framework - mappings.
The problem is that I need to have nested object. Here is an example
public class SessionModel extends RealmObject {
private UserModel userModel;
private ExpirationDate expirationDate;
}
As you can see the members are not simple types, but classes instead. Therefore it is problematic to map them correctly.
I wonder if there is any way to use custom retriever or mapper to get collect all objects manually and return a model with all fields set.
Thank you
I'm using lombok's annotation #Data when writing pojos because it automatically generates constructor, hashCode as well as other methods for me. It worked like a charm until I was trying to use #Data in such a pojo class.
#Data
public class MyPojo {
private final String name;
private final int from;
private final int to;
// other fields
}
What I need to do is to restrict values of from and to when creating this pojo so that to will always be greater than from, but it seems that in order to achieve this logic, I have to rewrite the constructor all by myself with lots of code similar to this.name = name.
PS: I think using super from inheritance could be a workaround, but it may make the program harder to be understood.
Is there any better way to satisfy this need?
#Data annotation is not providing any way to validate construction arguments. I feel you need to annotate your pojo with #Getter #Setter #ToString #EqualsAndHashCode annotations and write constructor on your own.
Looking at Lombok's website, I don't see any way to restrict constructor parameters to specific values, especially relative to another variable that may have not been initialized yet. You'll probably have to create a concrete constructor for this class.
but it may make the program harder to be understood
I really wouldn't worry about that as you're already using Lombok, which would make any big program very confusing when trying to track down a specific field/method.
I have some Entities that look like this:
#Entity
public abstract class AbstractEntity{
#Id
private Long id;
String name;
User author;
#Lob
byte[] data;
}
public class EntityOne extends AbstractEntity{
// nothing new
}
public class EntityTwo extends AbstractEntity{
// nothing new
}
public class EntityThree extends AbstractEntity{
// nothing new
}
The byte[] defined in the superclass is the interesting part of each subclass entity. The reason I want to subclass is to enforce typing rules, as some parts of the program require EntityThree, while some parts of the program require EntityTwo. the byte[] will have completely different meaning from subclass to subclass.
It feels a little strange, because I don't expect that any of the subclasses will add any fields or methods... So i use inheritance only as a typing tool.
Is this a reasonable design? A better way to accomplish this? Does it break any best practices?
It is a good OO practice. For the database, use the SINGLE_TABLE Inheritance strategy (the default), and maybe use a custom #DiscriminatorValue per subclass, otherwise you'll get classnames in your table.
From a DBA perspective, there is no difference between this and using a single class with a property TYPE.
For OO, the subclasses can be much more usefull, e.g. you can use it to implement certain methods differently or implement the visitor or strategy pattern instead of tedious if-then-else or instanceof structures.
It's hard to say without knowing the exact use-case, but it looks like you just want to reuse the common fields in all the entities, but that no other entity will have references to AbstractEntity - only to one specific subclass. In this case, you should map the superclass with #MappedSuperclass rather than with #Entity. Each entity will have its own table, and can override the mapping defined in the mapped superclass.
Note that if I'm mistaken, and you really need an entity inheritance, using instanceof, at least with Hibernate, will cause problems, because you might have a proxy to the base class, which doesn't know yet the exact subclass the foreign key is pointing to, and which is thus not an instance of any of the subclasses.