Lombok: 1.16.18
Eclipse: Oxygen
I have an object with #Getter and #Setter as a base object:
#Getter
#Setter
#EqualsAndHashCode(of="uuid")
public abstract class BaseEntity implements Serializable,Auditable {
Auditable requires setCreatedBy, which is included in BaseEntity.
However, the following object, which extends BaseEntity, receives an error of "The type Login must implement the inherited method Auditable.setCreatedBy(String)"
#Getter
#Setter
public class Login extends BaseEntity{
Looking on the outline pane, setCreatedBy is properly generated on BaseEntity, but does not exist on Login. What am I configuring wrong?
Not sure what happened, but a full rebuild eventually fixed it. Not sure that was the issue though, as I had done several full builds since upgrading lombok.
Related
I have a java EE web application in which a particular injection causes following error:
WELD-001408: Unsatisfied dependencies for type GenericDAO with qualifiers #Default
MyBean
#Stateless
public class MyBean extends CustomBean<Entity> {
...
}
CustomBean
public class CustomBean<T extends Serializable> implements Serializable {
#Inject
private GenericDAO<T> genericDAO;
}
GenericDAO
public abstract class GenericDAO<T extends Serializable> implements Serializable {
...
}
The issue appears only if a beans.xml is defined in the application. Deleting this, solves also the issue. In my case beans.xml is needed. Also when removing the GenericDAO<T> genericDAO; injection from the CustomBean, the error does not appear anymore. Also the rest of my injection in other classes, seem to work without any issue.
I've tried to solve that by creating an interface of GenericDAO and inject the interface instead. Also tried to with several anotations like #Local , #Dependent etc but i stumble upon different errors every time.
I am attempting to use QueryDSL with SpringData plus a Mongo repository.
Here is a simplification of my three levels of a document class hierarchy:
Top-Level Entity class
public abstract class AbstractEntity<T extends Serializable> {
public abstract T getId();
...
}
Base class for Document (Mongo) entities
import org.springframework.data.annotation.Id;
import com.querydsl.core.annotations.QueryEntity;
#QueryEntity
public abstract class DocumentEntity extends AbstractEntity<String> {
#Id
private String id;
public DocumentEntity() {
}
public String getId() {
return id;
}
...
}
Actual entity/document implementation
import org.springframework.data.mongodb.core.index.TextIndexed;
import org.springframework.data.mongodb.core.mapping.Document;
import com.blah.data.entity.DocumentEntity;
import com.querydsl.core.annotations.QueryEntity;
#QueryEntity
#Document(collection="Manufacturers")
public class Manufacturer extends DocumentEntity {
#TextIndexed
private String name;
public Manufacturer() {
}
...
}
The primary version numbers of consequence here, I believe, are
SpringBoot: 1.5.9.RELEASE
QueryDSL: 4.1.4
Here is my plugin configuration:
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.1.3</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/java</outputDirectory>
<processor> org.springframework.data.mongodb.repository.support.MongoAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
The "Q" classes are generated successfully in my maven build. However, my QDocumentEntity query class extends BeanPath and my QManufacturer query class extends EntityPathBase. This seems to be the source of the issue.
When I launch my application, I get an exception with the following root cause:
Caused by: java.lang.ClassCastException: com.blah.data.entity.QDocumentEntity cannot be cast to com.querydsl.core.types.EntityPath
at org.springframework.data.querydsl.SimpleEntityPathResolver.createPath(SimpleEntityPathResolver.java:59)
at org.springframework.data.mongodb.repository.support.QueryDslMongoRepository.<init>(QueryDslMongoRepository.java:85)
at org.springframework.data.mongodb.repository.support.QueryDslMongoRepository.<init>(QueryDslMongoRepository.java:67)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:142)
Based on this error, it seems that the super-class, DocumentEntity, should have been generated as extending EntityPathBase as well.
I'm not sure if it is relevant or not, but the AbstractEntity and DocumentEntity classes are in a separate maven module.
Am I missing something that is required to mark the superclass as an entity to the plugin? How can I force the generator to see my superclasses as entities?
So far, I've discovered 2 things. At this point, these two things are enough to be a workaround.
I ran the maven build from within Eclipse so that I could step through and debug what the annotation processor was doing. This led me to my first realization.
My parent class, DocumentEntity, was not being recognized as an Entity in com.querydsl.apt.ExtendedTypeFactory.createClassType(). The initial determined type was TypeCategory.SIMPLE and it never got flipped to TypeCategory.ENTITY because none of the defined entityAnnotations were present on the parent class. In order for it to be recognized as an entity, there has to be one of the defined annotations: entity, supertype or embeddable. Springframework's MongoAnnotationProcessor defined these as Document.class, QuerySupertype.class and QueryEmbeddable.class.
So, I added #QuerySupertype to my DocumentEntity class and got a different errror.
/target/generated-sources/java/com/blah/entity/QManufacturer.java:22: error: cannot find symbol
public final com.blah.data.entity.QDocumentEntity _super = new com.blah.data.entity.QDocumentEntity(this);
^
symbol: class QDocumentEntity
location: package com.blah.data.entity
1 error
As I mentioned in the OP, the parent class(es) are in another module. If I move the DocumentEntity (with the appropriate annotation) into the same module, it seems to work as expected. The QDocumentEntity class correctly extends EntityPathBase.
I wont' mark the answer as accepted yet, because in my mind it isn't quite answered even though I'm able to make a change and move on.
I don't know if it has to do with the timing of the APT processing for each module or what.
I really would like to have a base "Document" entity class that is in a sharable module and then have specific child modules extend from that and still get the appropriate Q classes generated. My assumption is that I'm still missing something.
When time permits, I may try to step through the APT processing some more to see if I can get to the bottom of it.
I would like to annotate a method with Spring Data #Id but it only works with fields, despite the fact that the annotation can be used on methods.
Is there a way to use #Id on methods too?
I'm using Spring Boot 1.3.0.RELEASE
EDIT
Actually I have this interface that will have an instance being created at runtime.
import org.springframework.data.annotation.Id;
#Document(indexName = "index", type = "document")
public interface Document {
#Id
Integer getId();
}
And this repository.
public interface DocumentRepository extends ElasticsearchCrudRepository<Document, Integer> {
}
Problem is that SimpleElasticsearchPersistentProperty from spring-data-elasticsearch 1.3.0.RELEASE always look for fields:
https://github.com/spring-projects/spring-data-elasticsearch/blob/1.3.0.RELEASE/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java
That way if I create an asbtract class instead and put #Id on a field, everything works fine.
The #Id annotation does work on properties, i.e. you can put it on getters, setters or fields. If this does not work something is wrong. Possible reasons are:
the names don't fit the property conventions
you are using the wrong #Id annotation
It does not work on arbitrary methods because Spring Data wouldn't be able to determine a name for that non-property, which in turn is required for many features.
In my JPA code i use:
#MappedSuperclass
public abstract class BaseEntityVotes<T> extends BaseEntity {
/**
* The entity this vote belongs to.
*/
#ManyToOne
#NotNull
private T entity;
But Eclipse can't validate: "Target entity "java.lang.Object" is not an Entity".
(no error in IntelliJ)
I tried to change the type parameter to <T extends BaseEntity> (BaseEntity is also a MappedSuperclass) but this only changes the error text accordingly. Is this a real problem? Or is this a bug in eclipse?
In this regard i found a fixed bug. But this didn't helped. So is there a fix or work around to get rid of this error or can i fix the code in some way?
I've updated my project from GWT 2.4.0 to GWT 2.5.1 and suddenly a specific RPC serialization has stopped work (all other are still working).
I have this class:
public class StatusChangeMapEntity extends RecordStamp implements Serializable {
private HashMap<WFStatus, Pair<WFPhase, ArrayList<Pair<AppUser, Date>>>> map;
...
...
}
The exception message is:
Attempt to deserialize an object of type class Pair when an object of type class Slide is expected
The class Slide extends StatusChangeMapEntity and is the object that is being deserialized.
Any ideias how to solve this problems?
Thanks.
I've managed to solve this problem. Basically I've created a class extending the HashMap:
public class MapStatusChanges extends HashMap<WFStatus, Pair<WFPhase, ArrayList<Pair<AppUser, Date>>>> {
...
}
And then created a CustomSerializer to the MapStatusChanges.
It's not a generic solution, but it works until this problem is solved at GWT.
Hope this helps....