Spring Data JPA and QueryDSL - No property find found for type - jpa

I'm using Spring JPA 1.7 and QueryDSL 3.5.1. I am getting 'No property find found' error.
Here are my classes.
#Entity
#Table(name="Device")
public class Device implements Serializable {
private static final long serialVersionUID = 1L;
#NotEmpty
#Id
#Column(name="deviceId")
private String deviceId="";
#Column(name="accountId")
private String accountId="";
#Column(name="groupId")
private String groupId="";
#Column(name="equipmentType")
private String equipmentType="";
#Column(name="deviceCode")
private String deviceCode="";
#Column(name="deviceType")
private String deviceType="";
#NotEmpty
#Column(name="simId")
private String simId="";
#NotEmpty
#Column(name="imeiNumber")
private String imeiNumber="";
#Column(name="simPhoneNumber")
private String simPhoneNumber="";
#Column(name="driverId")
private String driverId="";
#Column(name="pushpinId")
private String pushpinId=""; //who registered device? JMA/MDM/JAMS
#Column(name="isActive", columnDefinition="INT(1)")
private boolean isActive = false;
#Column(name="displayName")
private String displayName="";
#Column(name="description")
private String description="";
#Column(name="notes")
private String notes="";
#Column
#JsonSerialize(using=DateSerializer.class)
private long creationTime;
#Column
#JsonSerialize(using=DateSerializer.class)
private long lastUpdateTime;
//Getters and setters
}
public interface DeviceRepository extends PagingAndSortingRepository<Device, String>, DeviceRepositoryCustom {
public Page<Device> findAll(com.mysema.query.types.Predicate predicate, Pageable pageable);
}
public interface DeviceRepositoryCustom {
public List<Device> selectByEquipmentTypeAndAnyColumnLike(String equipmentType, String creationTime, String searchField, String searchText, boolean hasPushId);
}
public class MdmPredicates {
public static com.mysema.query.types.Predicate anyFieldLike(String field, String text) {
QDevice device = QDevice.device;
//Do something later
return device.deviceId.contains(text);
}
}
Here is the error log:
aused by: org.springframework.data.mapping.PropertyReferenceException: No property find found for type entities.Device
at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:75)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:327)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:353)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:307)
at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:271)
at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:245)
at org.springframework.data.repository.query.parser.Part.<init>(Part.java:72)
at org.springframework.data.repository.query.parser.PartTree$OrPart.<init>(PartTree.java:188)
at org.springframework.data.repository.query.parser.PartTree$Predicate.buildTree(PartTree.java:277)
at org.springframework.data.repository.query.parser.PartTree$Predicate.<init>(PartTree.java:257)
at org.springframework.data.repository.query.parser.PartTree.<init>(PartTree.java:68)
at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:57)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:90)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:162)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:68)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:290)
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:158)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:162)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:44)
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:168)
I know that the error happens when I don't use real column name instead of property name. But the property names in the class are all same with column names.
Would you please tell me what I am I missing?
Your help would be appreciated.

Related

Spring MongoDB: Auditing one-to-many relation subdocument

I am currently working on a self-taught project, thus I am a beginner in MongoDB and I am struggling to audit a subdocument in an one-to-many relation. For some reason none of the new records inserted in this collection is being audited, although audit is working fine for all the other collections.
Below is the structure of the collections in my project:
User document is the main Document - auditing ok
Provider is an embedded subdocument in User (One-to-One) - auditing ok
Address is an embedded set of documents in Provider (One-to-Many) auditing fail
public class User extends Audit<String>{
#Id
private String id;
private String email;
private String firstName;
private String lastName;
private String salt;
private String password;
private String role;
private Boolean isVerified;
private String userTempCode;
private LocalDateTime deactivationDate;
private Provider provider; // This subdocument gets audited no problem
...
public class Provider extends Audit<ObjectId>{
private ObjectId id = new ObjectId();
private LocalDate dob;
private String phone;
private Double price;
private Object geoLocation;
private Set<WeekDays> days;
private Set<TimeRange> hours;
private Set<Address> addresses; // Here is where I am having trouble, the createdBy, createdDate and so on, are not working
private String userId;
private LocalDateTime deactivationDate;
private Set<Reviews> ratings;
....
public class Address extends Audit<ObjectId>{
#Id
private ObjectId id = new ObjectId();
private String street;
private String street2;
private String city;
private String province;
private String country;
private String postalCode;
...
//Below My Audit class inherited by all documents
#Data
public abstract class Audit<T> implements Persistable<T> {
#CreatedBy
private String createdBy;
#CreatedDate
private LocalDateTime createdDate;
#LastModifiedBy
private String lastModifiedBy;
#LastModifiedDate
private LocalDateTime lastModifiedDate;
#Version
public Integer version;
}
So, why is my Set< Address> not being audited whereas the other documents are ok, am I missing something here?
Thank you!

Eclipselink translatedsqlstring exception

I have a simple JPA entity with #AdditionalCriteria mentioned for the login language. I also have specified a query redirector for this class. When I attempt to get the translated sql string in the query redirector, I get a null pointer exception. The reason is that the field in the entity is called lang and the additional criteria parameter is LOGIN_LANGUAGE. The exception is thrown when the line 273 of class org.eclipse.persistence.internal.expressions.ParameterExpression is executed.
My JPA entity looks like this
#QueryRedirectors(allQueries=VPMQueryRedirector.class)
#AdditionalCriteria(value = "this.lang = :LOGIN_LANGUAGE")
public class AuthorityTextView extends EntityCommons implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name = "AUTHORITYID", length = 36)
private String authorityId;
#Id
#Column(name = "LANG", length = 2)
private String lang;
#Column(name = "AUTHORITYTEXT", length = 255)
private String authorityText;
#Column(name = "DEFAULTUSED")
private Boolean defaultUsed;
public String getAuthorityId() {
return authorityId;
}
public String getLang() {
return lang;
}
public String getAuthorityText() {
return this.authorityText;
}
public Boolean getDefaultUsed() {
return this.defaultUsed;
}
}
My Query Redirector is listed below
public class VPMQueryRedirector implements QueryRedirector {
private static final long serialVersionUID = 3912645701055442481L;
private Logger logger = LoggerFactory.getLogger(getClass());
#Override
public Object invokeQuery(DatabaseQuery query, Record arguments, Session session) {
query.setDoNotRedirect(true);
String translatedSQLString = query.getTranslatedSQLString(session, arguments);
}
I have create a bug under eclipselink, but there hasn't been any updates yet if the observation is correct or not.

Map multiple fields to one with MapStruct

I have these 3 classes in separate files
public class Book {
#Id
#GeneratedValue
private Long id;
#NonNull
private String title;
#NonNull
private Author author;
}
public class Author {
#Id
#GeneratedValue
private Long id;
#NonNull
private String firstName;
#NonNull
private String lastName;
}
public class BookDTO {
private Long id;
#NonNull
private String title;
#NonNull
private String author;
}
I have the following mapper
#Mapper
public interface BookMapper {
BookMapper INSTANCE = Mappers.getMapper(BookMapper.class);
#Mappings({
#Mapping(source = "author.lastName", target = "author")
})
BookDTO toDTO(Book book);
}
this currently only maps the lastName and works, and I want to map the author string in Book with
author.firstName + " " + author.lastName
how could I do that? I have not been able to find anything in the MapStruct Documentation.
MapSruct does not support mapping multiple source properties into a single target property.
You have 2 ways to achieve this:
Using Mapping#expression
#Mapping( target = "author", expression = "java(book.getAuthor().getFirstName() + \" \" + book.getAuthor().getLastName())")
Using #AfterMapping or #BeforeMapping
#Mapper
public interface BookMapper {
BookMapper INSTANCE = Mappers.getMapper(BookMapper.class);
#Mapping(target = "author", ignore = true)
BookDTO toDTO(Book book);
#AfterMapping
default void setBookAuthor(#MappingTarget BookDTO bookDTO, Book book) {
Author author = book.getAuthor();
bookDTO.setAuthor(author.getFirstName() + " " + author.getLastName());
}
}

Mapping & fetching entities with composite keys using spring data JPA

I have Spring MVC and Data JPA. I am trying to do mapping tables I have. The structure is like below:
Device
--------------
PK deviceId
deviceName
Setting
--------------
PK deviceId
PK packageName
PK name
value
And I have classes for those tables:
#Entity
public class DeviceSetting implements Serializable {
#EmbeddedId
private String deviceId
private String deviceName;
#ManyToOne
#JoinColumn(name="deviceId", referencedColumnName="deviceId", insertable=false, updatable=false)
private Device device;
//Setters and Getters
}
#Embeddable
public class DeviceSettingPk implements Serializable {
private String deviceId;
private String packageName;
private String name;
public DeviceSettingPk(){}
public DeviceSettingPk(String deviceId, String packageName, String name) {
super();
this.deviceId = deviceId;
this.packageName = packageName;
this.name = name;
}
//Setters and Getters
}
#Entity
public class Device implements Serializable {
private static final long serialVersionUID = 1L;
#NotEmpty
#Id
#Column(name="deviceId")
private String deviceId;
private String deviceName;
//Getters and Setters
}
But I did not get device data when I put device and setting data has same deviceId and queried DeviceSetting by using repository.findOne(deviceId);
What else do I need to do to get the device data? Any advice would be helpful. Thanks.
Change the mapping as follows.
#Entity
public class DeviceSetting implements Serializable {
#EmbeddedId
private DeviceSettingPk deviceSettingId;
#ManyToOne
#JoinColumn(name="deviceId", referencedColumnName="deviceId", insertable=false, updatable=false)
private Device device;
//Setters and Getters
}
And then use the following code to lookup.
DeviceSettingPk id = new DeviceSettingPk(deviceId, packageName, name);
// use the deviceSettingRespository to lookup
repository.findOne(id);

How to handle compound key with relationship in JPA2 and Spring Data JPA?

I have a problem to handle mapping object relationship for mysql tables.
I have 2 tables shown below:
Device
-----------
deviceId PK
deviceName
ApkInfo
--------
id PK
packageName
appName
deviceId FK
And then here are my classes:
#Entity
#Table(name="Device")
public class Device implements Serializable {
#Column
#Id
private String deviceId;
#Column
private String deviceName;
//getters and setters
}
#Entity
#Table(name="ApkInfos")
public class ApkInfo implements Serializable {
#Column
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private int id;
#Column
#Id
private String packageName;
#Column
private String appName;
#Column
#Temporal(TemporalType.TIMSTAMP)
private Date installDate;
#ManyToOne
#JoinColumn(name="deviceId" referencedColumnName="deviceId")
private Device device;
//getters and setters
}
This works for me, but I want to use compound key, deviceId and packageName, in ApkInfos table.
#Entity
#Table(name="ApkInfos")
public class ApkInfo implements Serializable {
#Colum(instable=false, updatable=false)
#Id
private String deviceId;
#Column
private String packageName;
#Column
private String appName;
#ManyToOne
#JoinColumn(name="deviceId" referencedColumnName="deviceId")
private Device device;
//getters and setters
}
But when I tried to save an entity using Spring Data JPA repository, I got an error:
org.springframework.dao.InvalidAccessApiUsageException: Class must not
be null, nested exception is java.lang.IllegalArgumentException: Class
must not be null
ApkInfo apkInfo = new ApkInfo();
apkInfo.setDeviceId("1234");
apkInfo.setPackageName("aaa");
apkInfo.setAppName("myapp");
apkInfo.setInstallDate(new Date());
apkInfo.setDevice(new Device("1234"));
repository.save(apkInfo);
And device has the deviceID '1234' already exists in the Device table.
I created a separate primary key class added #IdClass in the ApkInfo class. It works fine now, thanks. I am going to have a look at EmbeddedId more later.
I added #IdClass at the entity class and #Id for the packageName property. Also I made insert, update false for the One-to-many column.
#Entity
#Table(name="ApkInfos")
#IdClass(ApkInfo.class)
public class ApkInfo implements Serializable {
#Column #Id private String deviceId;
#Column #Id private String packageName;
#ManyToOne
#JoinColumn(name="deviceId" referencedColumnName="deviceId", insetable=false, updatable=false)
private Device device;
//getters and setters missing
}
Primary key class has only setters and overrides equals and hasCode methods.
public class ApkInfo implements Serializable {
private String deviceId;
private String packageName;
public ApkInfo(){}
public ApkInfo (String deviceId, String packageName){
this.deviceId = deviceId;
this.packageName = packageName;
}
public String getDeviceId(){
return this.deviceId;
}
public String getPackageName(){
return this.packageName;
}
#Override
public boolean equals(Object obj){
return (obj!=null &&
obj instanceof ApkInfoPk &&
deviceId.equals(((ApkInfoPk)obj).getDeviceId()) &&
packageNames.equals(((ApkInfoPk)obj).getPackageName()) );
}
#Override
public int hashCode(){
super.hashCode();
}
}