Modify object serialization depending on what class is being serialized - java

So my goal is to return some objects as the response body from a Spring REST controller. The thing is, these two objects point each other, something kind of like this:
public class Person {
private Set<Team> teams;
}
public class Team {
private Set<Person> members;
}
If I return these two objects from a controllers mapping method right away, the generated response will be infinite and will probably crash the browser, because the members set has people, and each person has a set of teams, and so on, and everything gets returned infinitely.
How can I manage, instead of showing the whole list of, say, members, to display just the name of each of the members?
Any help will be much appreciated, thanks!

If you are using jackson then you must use jackson provided solution to problem you are mentioning.
#JsonManagedReference
#JsonBackReference
Also look at this link which might be helpful :
Infinite Recursion with Jackson JSON and Hibernate JPA issue,
Also
https://github.com/FasterXML/jackson-annotations/wiki/Jackson-Annotations#object-references-identity

Related

Single table inheritance view and application solution for Spring Boot and Thymeleaf

I decided to use single table inheritance which results in having multiple classes and I can't access the child's fields through a parent object in the view part of the application. So far I didn't find a nice solution how to deal with it in Thymeleaf. What does it mean?
Before I split my classes to use single table inheritance I could easily pass 1 object class that contained all the information needed to create or display the object but it had too many fields that would be null. With multiple classes thymeleaf doesn't really allow you to cast objects to a different type(and from what I understand it wouldn't be a good practice to do that in a view part of the application). So what is really the best way to deal with this problem?
I can come up with ideas like:
Create a DTO that contains the fields from all the classes and transform the objects to this class, it would be great in a create-view (POSTing DTO and then creating an object from it and adding to the database). But if I used this method for displaying information then it would mean casting each of the objects to a DTO class which kind of misses the point of single table inheritance in my opinion. I feel like this is too similar to going back to no inheritance at all.
Passing multiple objects or a parent object + a different object that would hold the rest of the information that the parent class doesn't hold. This also seems kind of weird.
Adding one method to a parent class per sub-class additional field and overwrite them in the sub-classes to return actual values while parent would return null. Not sure if this would fix the problem of creating the objects from a view though.
Let's assume this example with three simple classes where Person is a parent class and Client and Employee are children of it. I will skip getters, setters and constructors for simplicity.
Person main class that holds shared fields
#Entity
#Inheritance
#DiscriminatorColumn(name = "person_type", discriminatorType = DiscriminatorType.STRING)
public abstract class Person {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
int personId;
int age;
String name;
}
Client class that extends person with additional field favouriteProduct
#Entity
#DiscriminatorValue(value= "CLIENT")
public class Client extends Person {
String favouriteProduct;
}
Employee class that extends person with additional fields salary and position.
#Entity
#DiscriminatorValue(value= "EMPLOYEE")
public class Employee extends Person {
String position;
int salary;
}
Given this simple structure I would like to create Employee and Client objects through a single form via a POST request and also display them together in a different view with their fields that are unique to each subclass. Problem is that I would need to pass an object that holds all the fields to the view to actually make it work which comes back to the problem and solutions that I came up with. Is there any correct way or best practice how to deal with this? I thought DTOs should rather scale down from full objects to objects with less fields.
Conclusion: if the answer isn't really that simple then what is really the use of single table inheritance in this case and why isn't it a good idea to just go back to 1 table implementation? I already know about polymorphic queries and it is a nice bonus but so far I can't really deal with the problem I explained above. Thanks in advance!
I don't know about Thymeleaf (sorry!), but I do know about object-oriented programming a bit. Leaving frameworks aside and talking from a pure OO perspective, parent classes know nothing about their children (inheritors). Only the opposite can be true, and that's if you use the appropriate access modifiers. Given that said, I believe you can not do what you want unless there is some ugly framework black magic going under the hood haha.

Does methods should manipulate lazy collections?

I'm wondering if method should manipulate lazy collections?
This is example:
public class Person {
// lazy collection
#ManyToOne(fetch = FetchType.LAZY)
private List<Friend> friends;
public Friend findFriend(String name) {
//pseudo code
return friends.findByName(name);
}
}
Does findFriend is correct method? When I use it in transactional service method then will be Ok but someone may use it outside transaction and then exception occurs.
Is it bad practice to create methods which manipulate on lazy collections?
A good interface makes it easy to do the right thing but hard to do the wrong thing.
In your example any client code has to know about that precondition that you mentioned. That is not wrong by default, but makes it easy to cause problems that will only show up at runtime.
The minimum thing here could be to improve the names of this class /method to at least make that precondition more "explicit".

Multiple JaxB Marshalling profiles

I'm looking to have some conditional marshalling completed with jaxb. Something like this:
Class A{
//Only marshall when condition X applies
public String fieldOne;
//Only marshall when condition Y applies
public String fieldTwo;
//Always marshall
public String fieldThree;
}
Essentially I have 2 different Web Service methods which use the same model, but I need the information sent to be different on each of these web service methods.
My best option so far would be to create a custom XMLJavaTypeAdapter which verifies some conditional logic. The adapter would return null when I don't want the object, when I do need it marshalled it would return itself.
I'm looking to see if anyone has a better alternative. My jaxb context is quite complex and already has a few layer of adapters.
Thanks in advance.
My best option so far would be to create a custom XMLJavaTypeAdapter
which verifies some conditional logic. The adapter would return null
when I don't want the object, when I do need it marshalled it would
return itself.
I've been there and done that, it gets very messy very fast. If you can use MOXy (I see your post is tagged with moxy), you can can use the XmlNamedObjectGraph annotation to create named profiles of elements that are included when you instance is serialized.
Blaise Doughan (team lead for the MOXy project) explains it better than I can.
Blaise's blog post shows how to use annotations, but he also wrote a page on the EclipseLink wiki that shows how to do it programmatically.

jackson deserialization into pojos

I'm trying to deserialize JSON Object coming from an application I can't control. Here my JSON :
{"assembly":
{"name":"mm9",
"id":32,
"chromosomes":[
{"chromosome":
{"name":"MT"}
}]}}
My Pojos, are
class Assembly{
private String name;
private int id;
private ArrayList<Chromosome> chromosomes;
// getters & setters
}
class Chromosome {
private String name;
//getter/setters
}
But it's not working because of the extra fields "assembly" & "chromosome", so with a JSON like :
{"name":"mm9",
"id":32,
"chromosomes":[
{"name":"MT"}
] }}
it simply working.
Is there a way to modify configuration or something to achieve this without create more complex POJOS?
The problem is that in the first JSON snippet, chromosomes is a dictionary (Map), of which one of the entries (chromosome) happens to correspond to your Chromosome object.
A more accurate direct mapping to a Java class would be
class Assembly{
...
private Map<String, Chromosome> chromosomes;
}
Since you mention you can't control the format of the source JSON, you may want to look into using custom deserializers, or perhaps using the streaming support from Jackson rather than ObjectMapper for direct mapping, if you aren't happy changing your POJOs in this way.
By the way, it is best to refer to collections by their interface type (List) rather than a concrete type (ArrayList). It is very unlikely that code that refers to this class truly cares or needs to know that it is using an ArrayList, referring to just the List interface instead makes it a lot easier to swap other implementations in if needed (as a general principle).

Is it ever reasonable to nest Java inner classes more than one level deep?

Kushal Paudyal asked how deep you can nest inner classes in Java. The consensus is that while the language itself imposes no limit, the underlying OS and file system may.
Have you ever found a case where two or more levels of nested inner classes are helpful?
Update (11/28): If you consider enum classes, a second level of nesting can make sense. During some recent refactoring, I briefly had an outer class (an HTTP client), an inner class (an in-memory cache), and inside the inner class an enum class (for the cache eviction strategies). This seemed okay, but to #Thorbjørn's point, I continued by extracting the cache class and its inner enum up out of the HTTP client class.
No. I have not.
The standard example of a class inside a class is the Builder, where you have a subclass to help create a proper instance given a lot of possible configuration methods.
Personally I would consider a more complex case of nested classes an excellent example of code which needs refactoring.
I have not personally run into a case where more than one proved necessary. I could forsee a case where two may prove useful. I have trouble imagining more than two however.
The example I'm imagining is in Java GUI code. It may be useful in certain circumstances to have a class nested inside an already nested ActionListener.
If you're generating code from some data, nested classes can be a good way of avoiding name collisions.
I saw usage of number of levels of nested classes.
There is a legacy machine named Tandem (of HP), that originally runs code of COBOL/C. There are later "patches" that enable that machine of running java too. The variables structure of COBOL are naturally multi-leveled (even 5 levels is a common case), so in order to allow java to call to COBOL servers the java classes were also multi-leveled in order to simplify the conversion of the data between them.
I agree that this is a very uncommon case, but anyway...
I know I'm recycling an old thread, but it's new to me :)
We use multiple levels for our POJOs for deserializing JSON (with Jackson). Here is a tiny example (made up) of JSON we might get back from a RESTful web service:
{ success: true, response: {
sales: { item: "123", sales: 3, returns: 1 },
inventory: { item: "567", qty: 100 }
}
}
We used to have POJOs set up like:
public class Json1 {
private boolean success;
private JsonResponse response;
}
public class Json1Response {
private JsonResponseSales sales;
private JsonResponseInventory inventory;
}
public class Json1ResponseSales {
private String item;
private int sales;
private int returned;
}
public class Json1ResponseInventory {
private String item;
private int qty;
}
We have lots of these, with a POJO for each web service request we might make. This layout gave us a few niggling doubts:
Notice that this one, relatively simple example gave us four class files to keep up with. Now multiply that by 100s and then a 'difficulty factor' of 3 to account for the fact that most JSON is a lot messier than this. Thousands of files.
The field names are re-used all over the place, and the same field name might have different contents based on which web service. (Imagine that quantities might come back as strings from one web service, int from another, then multiply that by 100s.)
Since these things are tied together in a parent/child relationship, we decided to go with this layout instead.
public class Json1 {
private boolean success;
private JsonResponse response;
public class Json1Response {
private JsonResponseSales sales;
private JsonResponseInventory inventory;
public class Json1ResponseSales {
private String item;
private int sales;
private int returned;
}
public class Json1ResponseInventory {
private String item;
private int qty;
}
}
}
In this case, I'm nested two deep, but it might be more. Maybe up to four deep.
Sure - this is valid sometimes. I just did some a few minutes ago.
For example, in some test code I wrote, I wanted to set up some boilerplate that handled running multiple callables. The boilerplate needed to create multiple instances of a callable chunk of code. In this example, I'm creating an instance of a factory to pass into threadedTest, and that factory creates new callables.
#Test public void testXXXXXXXX() throws Throwable {
threadedTest(new CallableFactory() {
#Override public Callable<Request> create() {
return new Callable<Request>() {
// might have state
#Override public Request call() throws Exception {
// do the steps for this test
return ...;
}};
}});
}
Much more concise than creating two new classes where one just creates the other. Of course there's a readability penalty here until you're used to the style, though...
If you combined this with a template method to control transactions or database connect/close, this could end up three deep. (I've had some code like that; if you do it, make sure you write a dummy sample in your comments and explain the structure well)

Categories

Resources