I am working on a API to access data stored in a system. The system contains things like people, appointments and procedures associated with those appointments. My application will strictly be read-only.
I am using Spring w/ RowMapper to build objects such a "Person", "Appointment" and "Procedure". I have a DAO for each element. (ie: PersonDAO.getById(), PersonDAO.getByName(), ..).
The issue comes in that Appointment has a reference to a Person object. An it would be nice in the Person object to have a reference to that Person's appointments, but if I begin to load these it becomes a circular reference.
So, I guess my question is the right way to handle this just put the references (Ids) in the POJOs and then have the business layer(?) just make the right calls to get the information? Or is it ok to somehow pass around a reference to the DAO in the actual POJO so that I can lazily load the object objects when referenced? But then how do you handle the circular reference? When I have a Person and I lazily load all their appointments, those appointments will also have a Person associated with them. When I load this Person it could potentially have difference information from the Person I am loading Appointments for.
Person (object x) lazily load -> Appointments could lazily load Person (object x').
Since Person could have changed by the time I went to lazily load their appointments. I really need the Person object in Appointment to refer back to the same Person object.
I'm getting all caught up on this. I know I could just "make it work", but I want to try and find a good solution. I was thinking about using hibernate for this, but thought it was really just overkill. Maybe it isn't.
You're describing a bidirectional association, which Hibernate has specific (and generally very good) support for.
Read up on how to do it in the docs.
Rolling this by hand is going to be quite fiddly and bug-prone. I wouldn't recommend it. Use the the power of ORM tools like Hibernate, that's what they're there for.
Extending the suggestion of using Hibernate, I would recommend checking out the JPA annotation support that Hibernate supports ( I believe it's part of the J2EE spec). You can annotate your classes with a #ManyToMany annotation. Check out these docs:
https://www.hibernate.org/397.html
Related
I am working with REST API,
Is there any wrong if given the list of Model Class Objects as response directly to the user.
or should I need to map those Actual Model class to any POJA class before Returning?
eg :
if the API is forgetting all Users ("/Users")
then is it a good coding method to return directly
return userRepository.findAll();
or need to convert it to any List<UserPOJO> before returning?
Or is there any good codding standards?
From my experience, it is usually better to map the Entities to equivalent POJO classes.
Here are a few reasons:
1) Most of the time you do not need all the data that is stored in an entity. You can map only the subset that is needed in the response.
2) From a security perspective, it is always good to have some sort of a middle ground where you filter out the sensitive data that should not actually put in the response. Or only for certain users which you can decide during the mapping.
3) Hibernate objects are not plain objects, they are proxies. This may cause unnecessary lazy loading for example of #OneToMany and #ManyToMany relations. You should be able to control that and from my experience, Jackson loads all things possible, unless you annotate it with a #JsonIgnore.
Unless you are working with a very simple and not security-heavy app, then I would stay with Hibernate objects. But otherwise, which is most cases, I would go for the mapping.
Short version for the hasty:
There's various tables/entities in my domain model which have the same field (a UUID). There is a table where I need to link rows/instances of such entities to other JPA-managed entities. In other words, the instance of the field in that link table won't be known up-front. The two approaches I can think of are:
Use an abstract entity and a TABLE_PER_CLASS strategy, or
use an #MappedSuperClass store the class name of the instance in the link table as well, or something similar that lets me define logic for getting the actual instance from the right table.
Both have advantages and disadvantages in terms of complexity and performance. Which do you believe to be best, is there maybe a third option, or have you tried something like this in the past and would advice/strongly warn against?
Long version in case you want more background:
I have a database/object model wherein many types have a common field: a universally unique identifier (UUID). The reason for this is that instances of these types can be subject to changes. The changes follow the command model and their data can be encapsulated and itself persisted. Let's call such a change a "mutation". It must be possible to find out which mutations exist in the database for any given entity, and vice-versa, on which entity a stored mutation operates.
Take the following entities with UUIDs as an (extremely simplified) example:
To store the "mutations", we use a table/entity called MutationHolder. To link a mutation to its target entity, there's a MutationEntityLink. The only reason this data isn't directly on the MutationHolder is because there can be direct or indirect links, but that's of little importance here so I left it out:
The question comes down to how I can model the entity field in MutationEntityLink. There are two approaches I can think of.
The first is to make an abstract #Entity annotated class with the UUID field. Customer, Contract and Address would extend it. So it is a TABLE_PER_CLASS strategy. I assume that I could use this as a type for the entity field, although I'm not certain. However, I fear this might have a serious performance penalty since JPA would need to query many tables to find the actual instance.
The second is to simply use #MappedSuperClass and just store the UUID for an entity in the entity field of MutationEntityLink. In order to get the actual entity with that UUID, I'd have to solve it programmatically. Adding an additional column with the class name of the entity, or something else that allows me to identify it or paste it in a JPQL query would do. This requires more work but seems more efficient. I'm not averse to coding some utility classes or doing some reflection/custom annotation work if needed.
My question is which of these approaches seems best? Alternatively, you might have a better suggestion, or notice I'm missing something; for example, maybe there's a way to add a type column even with TABLE_PER_CLASS inheritance to point JPA to the right table? Perhaps you've tried something like this and want to warn me about numerous issues that would arise.
Some additional info:
We create the database schema, so we can add whatever we want.
A single table inheritance strategy isn't an option. The tables must remain distinct. For the same reason, joined inheritance doesn't seem a good fit either.
The JPA provider is Hibernate and using things that are not part of the JPA standard isn't an issue.
If the entities don't have anything in common besides having a uuid I'd use the second approach you describe: use MappedSuperclass. Making the common superclass an entity would prevent you to use a different inheritance strategy if needed, would require a table for that super entity even if no instances exist and from a business point of view it's just wrong.
The link itself could be implemented in multiple ways, e.g. you could subclass MutationEntityLink for each entity to map (e.g. CustomerMutationEntityLink etc.) or do as you described it, i.e. only store the uuid as well as some discriminator/type information and resolve programatically (we're using that approach for something similar btw.).
You need to use #MappedSuperclass while inheriting associations/methods/properties whereas TABLE_PER_CLASS is generally used when you have entity and sub-entities. If there are entities having an association with the base class in the model, then use TABLE_PER_CLASS since the base class behaves like an entity. Otherwise, since the base class would include properties/attributes and methods which are general to such entities not related to each other, using #MappedSuperclass would be a better idea
Example1: You need to set alarms for some different activities like "take medicine", "call mom", "go to doctor" etc. The content of the alarm message does not matter, you will need a reminder. So use TABLE_PER_CLASS since alarm message, which is your base class is like an entity here.
Example2: Assume the base class AbstractDomainObject enables you to create login ID, loginName, creation/modification date for each object where no entity has an association with the base class, you will need to specify the association for the sake of clearing later, like "Company","University" etc. In this situation, using #MappedSuperclass would be better.
I am currently working on a product that works with Hibernate (HQL) and another one that works with JPQL. As much as I like the concept of the mapping from a relational structure (database) to an object (Java class), I am not convinced of the performance.
EXAMPLE:
Java:
public class Person{
private String name;
private int age;
private char sex;
private List<Person> children;
//...
}
I want to get attribute age of a certain Person. A person with 10 children (he has been very busy). With Hibernate or JPQL you would retrieve the person as an object.
HQL:
SELECT p
FROM my.package.Person as p
WHERE p.name = 'Hazaart'
Not only will I be retrieving the other attributes of the person that I don't need, it will also retrieve all the children of that person and their attributes. And they might have children as well and so on... This would mean more tables would be accessed on database level than needed.
Conclusion:
I understand the advantages of Object Relational Mapping. However it would seem that in a lot of cases you will not need every attribute of a certain object. Especially in a complex system. It would seem like the advantages do not nearly justify the performance loss. I've always learned performance should be the main concern.
Can anyone please share their opinion? Maybe I am looking at it the wrong way, maybe I am using it the wrong way...
I'm not familiar with JPQL, but if you set up Hiernate correctly, it will not automatically fetch the children. Instead it will return a proxy list, which will fetch the missing data transparently if it is accessed.
This will also work with simple references to other persistent objects. Hibernate will create a proxy object, containing only the ID, and load the actual data only if it is accessed. ("lazy loading")
This of couse has some limitations (like persistent class hierarchies), but overall works pretty good.
BTW, you should use List<Person> to reference the children. I'm not sure that Hibernate can use a proxy List if you specify a specific implementation.
Update:
In the example above, Hibernate will load the attributes name, age and sex, and will create a List<Person> proxy object that initially contains no data.
Once the application accesses calls any method of the List that requires knowledge of the data, like childen.size() or iterates over the list, the proxy will call Hibernate to read the children objects and populate the List. The cildren objects, being instances of Person, will also contain a proxy List<Person> of their children.
There are some optimizations hibernate might perform in the background, like loading the children for other Person objects at the same time that might be in this session, since it is querying the database anyways. But whether this is done, and to what extend, is configurable per attribute.
You can also tell hibernate to never use lazy-loading for certain references or classes, if you are sure you'll need them later, or if you continue to use the persistent oject once the session is closed.
Be aware that lazy loading will of course fail if the session is no longer active. If for example you load a Person oject, don't access the children List, and close the session, a call to children.size() for example will fail.
IIRC the hibernate session class has method to populate all not-yet-loaded references in a persistent oject, if needed.
Best read the hibernate documentation on how to configure all this.
I have made an aggregate class named Question. This contains references to Answer, Category, Feedback objects. Should the QuestionRepository be the class that contains all methods quering the database that relates to the Question but also all the methods for quering the Feedback, Answer etc? Or should these be seperate classes such as QuestionRepository, FeedbackRepository and so on.
From the way you have explained , I am assuming that each Question will have 1 or more Answers , 1 or more Feedback and the Question belongs to a particular Category
Since the Answer and Feedback are dependent on Question and cannot exist independently , you can have a single QuestionRepository for these 3 entities .
Coming to Category , category is more of a static entity which IMO is a static list , so all such static entities can be grouped together in a StaticRepository
From the DDD web site :
For each type of object that needs global access, create an object
that can provide the illusion of an in-memory collection of all
objects of that type.
A repository is used when you need direct access to an entity, i.e. when there's no other convenient way to get hold of that entity than fetching it from a persistent store directly. In contrast, if you consider that the entity is most of the time easily obtainable through traversal of another object you've already got at hand, then there's no need for a repository. It seems to be the case with Answer, Category, and Feedback here.
Usually repositories are only for aggregate roots, though there may be exceptions.
I suggest you read the DDD blue book or some tutorial to get a basic comprehension of the DDD building blocks before you start building your domain model.
I've got a relatively simple class that is primarily backed by a Map<String,String>. I'd like to persist this class and be able search within the keys within the map. Based on this Stack Overflow question I get the feeling that Maps can only be persisted as a serialized blob.
I also see on the ORMLite website the following:
public class Account {
…
#ForeignCollectionField(eager = false)
ForeignCollection<Order> orders;
…
}
In the above example, the #ForeignCollectionField annotation marks
that the orders field is a collection of the orders that match the
account. The field type of orders must be either ForeignCollection
or Collection<T> - no other collections are supported. The
#ForeignCollectionField annotation supports the following fields:
Based on the above I get the impression that what I want isn't possible, but I thought I'd check here to be sure. I have it persisted in Hibernate, but I'd rather use something lighter like ORMLite!
One pretty easy solution is to have the getters and setters work with a JSONObject behind the scenes, and putting that object as a String in the database.
But then again, JSON isn't part of java-out-of-the-box so this may feel unneccesary if you're not using it anyway.
Yeah, there is no way in ORMLite to persist a Map. Keeping with the KISS principle, only the simple Collection class is supported. Set and Map have a lot more interface weight to them and will probably never be supported.
I don't have any super great work arounds for you. You could obviously use ForeignCollection and then have a local Map field that you create when you need to access the collection that way. Maybe an addOrder() method that would add it to the ForeignCollection and the Map.