JsonIgnore annotation is not working with Lombok - maven

I am facing really weird issue with Lombok and Jackson. Following of piece of code on which I am working.
#Getter
#Setter
#NoArgsConstructor
#XmlRootElement
public class Order{
//#JsonIgnore
#Getter(onMethod = #__(#JsonIgnore))
private boolean userPresent;
}
So what I want , this dto supposed to serialized as Json then this userPresent attribute should not come as response attribute. I though #JsonIgnore will work for me. But I think it as some issue with Lombok as per https://stackoverflow.com/a/57119494/2111677 article.
Then I changed the approach to use OnMethod.
Now , on eclipse compiling perfectly fine but when I am trying to compile using mvn then it gives me following error.
Could someone help me fix when its not working with maven.

The #__ style is for javac7. For javac8+ you have to use this variant:
#Getter(onMethod_=#JsonIgnore)
However, it is sufficient to have the #JsonIgnore annotation on either the field, the getter, or the setter. If it is present on at least one of those, the whole "virtual property" is ignored completely during (de-)serialization. So if that is what you want, you don't need that onMethod_.
If you want it to be ignored only during serialization, but not on deserialization, you have to add a #JsonProperty on the setter:
#JsonIgnore
#Setter(onMethod_=#JsonProperty)
private boolean userPresent;

It does not work, a workaround is using #JsonIgnoreProperties at class level:
#JsonIgnoreProperties({"email"})

This worked for me.
#RequiredArgsConstructor
#Setter
#NoArgsConstructor
#Entity
public class ProductColor {
#Id
#GeneratedValue
#NonNull
#Getter
private Long id;
#NonNull
#Getter
private String color;
#ManyToMany(mappedBy="colors")
#Getter(onMethod_ = #JsonIgnore)
private Set<Product> products;
}

Related

Cannot invoke "org.hibernate.mapping.PersistentClass.getTable()" because "classMapping" is null

I have an entity "MasterSegment" with a composite key as the primary key. This key has a reference to another entity "BkrApplication". When I start the app without Liquibase, tables are generated perfectly and everything works fine.
public class MasterSegment extends Auditable {
#EmbeddedId
private MasterSegmentId id;
#OneToOne
#MapsId("appId")
private BkrApplication app;
// getters setters omitted
}
#Embeddable
public class MasterSegmentId implements Serializable {
#Column
private String name;
#Column(name = "app_id", nullable = false)
private Long appId;
// getters setters omitted
}
The problem is when I try to generate a Liquibase migration using mvn clean install liquibase:diff, I get the following error: Cannot invoke "org.hibernate.mapping.PersistentClass.getTable()" because "classMapping" is null.
Without any hint in the exception message, and after many hours of debugging, I noticed that #MapsId causes the issue. I try to remove it and I got mapping issues.
Any help would be much appreciated.
Thanks

Ignore xml tags while serializing pojo fields to xml

I am using jackson library to map POJO to XML.
compile ('com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.9.0')
While serializing I need to ignore some of the fields. This is my POJO class. For example, the field lineNumber should be ignored.
#NoArgsConstructor
#AllArgsConstructor
#Getter
#XmlAccessorType(XmlAccessType.FIELD)
public class InvoiceLineItem {
#JacksonXmlProperty(localName = "LineNumber")
#XmlTransient
private Integer lineNumber;
#JacksonXmlProperty(localName = "ProductCode")
#XmlTransient
private String productCode;
#JacksonXmlProperty(localName = "ProductDescription")
#XmlTransient
private String productDescription;
}
I am using #XmlTransient with XmlAccessorType to ignore the fields. But the lineNumber field annotated with XmlTransient is not ignored while serializing.
Try adding the #JsonProperty(access = Access.WRITE_ONLY)
annotation to the lineNumber field.
Even thought it looks like a JSON thing,
the Jackson XmlMapper identifies the annotation and reacts accordingly.
Edit
The conclusion XmlMapper should support JSON serizlization is an example of the following, incorrect attempt at reasoning:
All men are mortal.
Socrates was mortal.
Therefore, all men are Socrates.
The XmlMapper is not a wrapper class around ObjectMapper.
It came after ObjectMapper and appears to share many features,
like the handling of some JSON annotation.

Why spring create tow identical links for self and rel?

I cannot get why spring create the same links for self and rel? Is there a way how to disable it? I think that this only my issue because I didn't meet such problem in docs I read.
Here is my entity mapping:
#Getter
#Setter
#Document
public class Ad {
#Id
private String id;
private String description;
private Banner banner;
}
#Getter
#Setter
public class Banner {
private String id;
private String filename;
}
Here is my repository:
#RepositoryRestResource
public interface AdRepository extends CrudRepository<Ad, String> {
}
I touch the following url: http://localhost:8558/ads
I don't use any projections. My app is quite primitive now. There is nothing specific.
Thanks in advance!
My only guess is that maybe you're missing hashCode/equals and that's causing a problem
This is by design. The rel-based link allows you to see all contexts, while self link serves as the canonical link.
To further clarify, adjust your repository definition to extend not CrudRepository, but instead PagingAndSortingRepository. The two links rendered for each aggregate root will immediately look slightly different due to extended templating options.

Spring Data Rest adding excerpt projection switches off lazy fetching

I'm new to Spring Data Rest and trying to play around with its basic concepts. Everything works well so far, but few days ago I noticed that the application performance suddenly dropped after putting the projections into business.
These are my entities, repositories and the projection
#Entity
public class Item {
#Id
#GeneratedValue(strategy = TABLE)
private long id;
private String code;
private String name;
#ManyToOne(targetEntity=Category.class)
#JoinColumn(name="category_id", referencedColumnName="id")
private Category category;
//getters & setters
}
#Entity
public class Category {
#Id
#GeneratedValue(strategy = TABLE)
private long id;
private String name;
#OneToMany(mappedBy="category", targetEntity=Item.class, fetch=FetchType.LAZY)
private Set<Item> items;
//getters & setters
}
#RepositoryRestResource(excerptProjection=ItemExcerpt.class)
public interface ItemRepository extends CrudRepository<Item, Long>{
}
#RepositoryRestResource
public interface CategoryRepository extends CrudRepository<Category, Long>{
}
#Projection(name="excerpt", types=Item.class)
public interface ItemExcerpt {
String getName();
}
So, all worked fine untill I added the excerpt projection to the ItemRepository #RepositoryRestResource(excerptProjection=ItemExcerpt.class)
Before doing this, when I hit http://localhost:9191/categories Hibernate output was as I expected it to be:
select
category0_.id as id1_0_,
category0_.name as name2_0_
from
category category0_
This is the output that I get after adding excerptProjection=ItemExcerpt.class
Hibernate:
select
category0_.id as id1_0_,
category0_.name as name2_0_
from
category category0_
Hibernate:
select
items0_.category_id as category4_1_0_,
items0_.id as id1_1_0_,
items0_.id as id1_1_1_,
items0_.category_id as category4_1_1_,
items0_.code as code2_1_1_,
items0_.name as name3_1_1_
from
item items0_
where
items0_.category_id=?
My conclusion is that the excerpt projection makes lazy fetching being ignored on #OneToMany relationship, which leads to a performance drop.
Does anyone know a way to bypass this issue, or is this maybe an expected behaviour?
It isn't exactly that excerpt projections make lazy fetching be ignored. More specifically, it is that an excerpt projection is telling spring data to include the excerpted data wherever a collection resource would be returned.
From the reference docs Projections Excerpts, "An excerpt is a projection that is applied to a resource collection automatically.". The unfortunate side-effect of this is that spring-hateoas then ignores that property and instead puts in the hypermedia link to the resource instead. There is no combination of annotations that i have found that will correct this behavior for you while preserving the output. #JsonIgnore will not prevent the extra queries. #RestResource(exported = false) will prevent the queries, but will also prevent the hypermedia link.

Spring Data JPA and Generics

I have an entity that looks like this
#Entity(name = "encounter_pdf_export")
public class EncounterPDFExport<T extends Encounter> implements Serializable {
public static final long serialVersionUID = 1L;
#Id
#GeneratedValue
private Long pdfExportId;
#Any(metaColumn = #Column(name = "encounter_type"))
#Cascade(CascadeType.ALL)
#AnyMetaDef(
idType = "long",
metaType = "string",
metaValues = {
#MetaValue(value = "FooEncounter", targetEntity = FooEncounter.class)
})
#JoinColumn(name = "encounter_id")
private T encounter;
The abstract type that I'm extending is:
public abstract class Encounter {
public abstract Long getEncounterId();
}
Here is my Spring Data Repository
#Repository
public interface EncounterPDFExportRepository extends PagingAndSortingRepository<EncounterPDFExport, Long> {
EncounterPDFExport findOneByEncounter_encounterId(#Param("encounterId") Long encounterId);
}
I am getting a stack trace when starting up the application related to to the findOneByEncounter_encounterId method:
Caused by: java.lang.IllegalArgumentException: Unable to locate Attribute with the the given name [encounter] on this ManagedType [com.iimassociates.distiller.domain.EncounterPDFExport]
at org.hibernate.jpa.internal.metamodel.AbstractManagedType.checkNotNull(AbstractManagedType.java:144)
at org.hibernate.jpa.internal.metamodel.AbstractManagedType.getAttribute(AbstractManagedType.java:130)
at org.springframework.data.jpa.repository.query.QueryUtils.toExpressionRecursively(QueryUtils.java:468)
at org.springframework.data.jpa.repository.query.JpaQueryCreator$PredicateBuilder.getTypedPath(JpaQueryCreator.java:300)
at org.springframework.data.jpa.repository.query.JpaQueryCreator$PredicateBuilder.build(JpaQueryCreator.java:243)
at org.springframework.data.jpa.repository.query.JpaQueryCreator.toPredicate(JpaQueryCreator.java:148)
at org.springframework.data.jpa.repository.query.JpaQueryCreator.create(JpaQueryCreator.java:88)
at org.springframework.data.jpa.repository.query.JpaQueryCreator.create(JpaQueryCreator.java:46)
at org.springframework.data.repository.query.parser.AbstractQueryCreator.createCriteria(AbstractQueryCreator.java:109)
at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:88)
at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:73)
at org.springframework.data.jpa.repository.query.PartTreeJpaQuery$QueryPreparer.<init>(PartTreeJpaQuery.java:116)
at org.springframework.data.jpa.repository.query.PartTreeJpaQuery$CountQueryPreparer.<init>(PartTreeJpaQuery.java:237)
at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:65)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:100)
I am assuming that either Spring Data JPA doesn't support abstracted/generic fields? If that's the case, would creating a #Query be a sufficient workaround?
Not sure if this will be helpful to anyone, but I did get this working.
Removed the abstract class and made it an interface with a single public getEncounterId() method
Modified FooEncounter to implement the above interface
Removed generics from the EncounterPDFExport class
Modified the encounter field to utilize the above interface rather than a generic
Apparently, I'm hitting some Hibernate bug/limitation when accessing fields within FooEncounter. Accessing Encounter within EncounterPDFExport works OK, though. I modified my Spring Data JPA Repository to look like the following (note the modification from finding by encounter.encounterId vs. just encounter):
#Repository
public interface EncounterPDFExportRepository extends PagingAndSortingRepository<EncounterPDFExport, Long> {
EncounterPDFExport findOneByEncounter(#Param("encounter") Encounter encounter);
}
The Hibernate bug in question seems to be related to https://jira.spring.io/browse/DATAJPA-836.

Resources