JPA Repository not working properly - jpa

I am new to Open JPA and I am migrating my application DB services from JPA with Hibernate as vendor provider to JPA with OpenJPA as vendor Provider. Everything is fine, but I am not able to migrate my repositories. I am getting below error:
Caused by: org.springframework.data.mapping.PropertyReferenceException: No property find found for
type com.entities.LevelPossibilityData
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:353)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:353)
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)
Here is my entity:
package com.entities;
import java.io.Serializable;
import java.math.BigDecimal;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import java.lang.reflect.Field;
#Entity
#Table(name = "LEVEL_POSSIBILITY_DATA", schema = "DEV")
#NamedQueries({
#NamedQuery(name = "LevelPossibilityData.findAllPossibilityGenIds", query = "SELECT distinct possibilityData.levelPossibilityGenId FROM LevelPossibilityData possibilityData where possibilityData.userCode is not null and possibilityData.possibilityType=?1 order by possibilityData.levelPossibilityGenId asc")})
public class LevelPossibilityData implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue
#Column(name = "LEVEL_SEQ_ID")
private BigDecimal levelSeqId;
#Column(name = "LEVEL_USER_CODE")
private String userCode;
#Column(name = "LEVEL_USER_POSSIBILITY_TYPE")
private String possibilityType;
#Column(name = "LEVEL_POSSIBILITY_GENERATOR_ID")
private String levelPossibilityGenId;
}
and my Repository:
package com.dao;
import java.io.Serializable;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import com.entities.LevelPossibilityData;
public interface LevelPossibilityDataRepository<ID extends Serializable> extends JpaRepository<LevelPossibilityData, Serializable> {
public List<LevelPossibilityData> findAllPossibilityGenIds(String possibilityType);
}
Can you please help me out in rectifying this error?

I was able to solve the issue by removing Named Queries from entity. I introduced queries directly into Repository by using #Query annotation.
Just one catch, if you are using openJPA and trying to use #Query in Repository, try to use full path of the entities used e.g.
use "com.entities.LevelPossibilityData" instead of "LevelPossibilityData" in your query i.e. your query should be "select level from com.entities.LevelPossibilityData level" instead of "select level from LevelPossibilityData level".
I hope this explaination will be helpfull. Thanks everybody for devoting time on this.

Related

Issue with custom Annotation created from javax.persistence.Entity annotation

We have a requirement to customize all SQL and NoSQL database annotation in Spring Boot application.
And able to do it for MongoDB but unable to do it for SQL database and getting a java.lang.IllegalArgumentException: Not a managed type: class com.entity.EmployeeEntity exception
SQL JPA is not working:
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import javax.persistence.Entity;
import org.springframework.core.annotation.AliasFor;
#Target(value = { TYPE })
#Retention(value = RUNTIME)
#Documented
#Entity
public #interface MyEntity {
#AliasFor(annotation = Entity.class)
String name() default "";
}
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import com.mt.mtamp.core.annotations.MtAmpEntity;
import com.mt.mtamp.core.annotations.MtAmpId;
import lombok.Data;
#Data
#MyEntity(name = "employee")
public class EmployeeEntity implements Serializable{
private static final long serialVersionUID = 1L;
#MtAmpId
private Long storeId;
private String storeName;
}
- **Exception**:
Caused by: java.lang.IllegalArgumentException: Not a managed type: class com.entity.EmployeeEntity
at org.hibernate.metamodel.internal.MetamodelImpl.managedType(MetamodelImpl.java:583) ~[hibernate-core-5.6.14.Final.jar:5.6.14.Final]
at org.hibernate.metamodel.internal.MetamodelImpl.managedType(MetamodelImpl.java:85) ~[hibernate-core-5.6.14.Final.jar:5.6.14.Final]

Spring boot JPA nnotationException: No identifier specified for entity, while having proper id

I have such DAO:
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.math.BigDecimal;
import java.util.UUID;
#Entity
#Table(name = "questionnaire_answer")
#Getter
#Setter
#NoArgsConstructor
public class QuestionnaireAnswer {
#Id
#Column(name = "id", nullable = false)
private UUID id;
and repository:
#Entity
#Table(name = "questionnaire_answer")
public interface QuestionaireRepository extends CrudRepository<QuestionnaireAnswer, UUID> {
sql:
CREATE TABLE questionnaire_answer (
id varchar(36) PRIMARY KEY,
...
)
but still I see an error:
AnnotationException: No identifier specified for entity:
what can I do wrong here ?
Blockquote
eh I am so blind, stupid mistake
#Repository should be in QuestionaireRepository
but I put there table and entity :)) it was end of my day..
today I realized what had happened.

Spring Data Rest - unable to update nested object with PUT or PATCH

I have Many-To-Many relation between Attribute and AttributeGroup. AttributeGroup contains many attributes and those attributes can be a children of more than one AttributeGroup.
Though Attribute is child of AttributeGroup, it is always created in its own repository, i.e., it is expected to have the Attribute created before AttributeGroup and when the child relationship is added during the creation of AttributeGroup.
Using attribute repo, I could do all the CRUD operations and using attributeGroup repo, successfully process the CRUD operations. During AttributeGroup creation, the relationship to Attribute also work as expected.
Next, if I want to change the relation, i.e., drop an existing Attribute and/or add another another attribute, it does not work.
I read that for updating the nested object PATCH works, but PATCH throws an exception
java.lang.IllegalArgumentException: Can not set java.lang.Long field Attribute.id to AttributeGroup
Please let me know what is wrong with this implementation.
AttributeGroup.java
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.util.List;
#Data
#Entity
#AllArgsConstructor
#NoArgsConstructor
public class AttributeGroup implements Serializable {
private static final long serialVersionUID = -8264102706248686536L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
String name;
String displayName;
#NotNull
#Size(min = 1)
#ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.MERGE, CascadeType.REFRESH})
List<Attribute> attributes;
}
Attribute.java
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
#Data
#Entity
#AllArgsConstructor
#NoArgsConstructor
public class Attribute implements Serializable {
private static final long serialVersionUID = 8806808817130076030L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
String name;
String value;
AttributeType attributeType;
ArrayList<String> values;
#ManyToMany(mappedBy = "attributes")
#ToString.Exclude
List<AttributeGroup> attributeGroups;
}
AttributeTye.java
public enum AttributeType {
TEXT("Text Only");
private final String attributeType;
AttributeType(String productType) {
this.attributeType = productType;
}
}
In bidirectinoal relationships, you need to syncronize both sides of arelationship to be able to delete an entity.
AttributeGroup is the owner of the relationship. So, it must have a method like below in it:
public void removeAttribute(Attribute attribute){
if(attributes.contains(attribute)){
attributes.remove(attribute);
attribute.getAttributeGroups().remove(this);
}
}
Also, in Attribute class you should have:
#PreRemove
void removeAttributeFromAttributeGroups(){
for (AttributeGroup attributeGroup : attributesGroups) {
attributeGroup.removeAttribute(this);
}
}
The same procedure is applied to Add operation.

Spring MVC / Hibernate / Eclipse - Why Automatically Generated Model Files?

I have a Spring MVC based Java project. This project uses hibernate for the ORM. I am also using Eclipse Kepler as an IDE. I have a question about the Model portion of my project. All of the .java files that I have that are the Model files have an equivalent named file that ends in an underscore. These equivalent files ending in the underscore were automatically generated "I think by the IDE". I have no idea why these files got generated and what their purpose is. Can someone shed some light on this and point me in the right direction? I feel this is either an incorrect IDE setting that is causing them to get generated or is being generated due to some configuration setting that I have within my project.
For instance I have a User.java and a User_.java file. I wrote the User.java but not the User_.java. The User_.java was generated automatically. The code for each of these files is below, the first block is the User_.java that was generated automatically.
package com.bah.iaat.model.data;
import javax.annotation.Generated;
import javax.persistence.metamodel.SingularAttribute;
import javax.persistence.metamodel.StaticMetamodel;
#Generated(value="Dali", date="2014-04-03T23:00:06.698-0400")
#StaticMetamodel(AnalyticAgenda.class)
public class AnalyticAgenda_ {
public static volatile SingularAttribute<AnalyticAgenda, Integer> id;
public static volatile SingularAttribute<AnalyticAgenda, String> name;
public static volatile SingularAttribute<AnalyticAgenda, String> desc;
public static volatile SingularAttribute<AnalyticAgenda, Integer> userGroupId;
public static volatile SingularAttribute<AnalyticAgenda, String> flag;
}
The next block of code is the code that I wrote:
package com.bah.iaat.model.data;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.hibernate.annotations.NamedQueries;
import org.hibernate.annotations.NamedQuery;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
#NamedQueries({#NamedQuery(name = "SelectAllUsers",query = "Select u from User u"),
#NamedQuery(name = "SelectUserByName",query = "Select u from User u where u.name =:uName"),
#NamedQuery(name = "findUserByIdentifier",query = "Select u from User u where u.name =:pId"),
#NamedQuery(name = "findUserIdByName",query = "select u.id from User u where u.name =:pName"),
#NamedQuery(name = "findUserByName",query = "select u from User u where u.name =:pName")})
#Entity
#Table(name="USERS")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="USER_ID")
private Integer id;
#Column(name="USER_NAME", unique=true)
private String name;
#Column(name="LAST_LOGIN")
private Date lastLogin;
#ManyToOne
#JoinColumn(name="USER_GROUP_ID" )
private UserGroup userGroup;
public User() {}
public User(String name, UserGroup userGroup, Date lastLogin){
this.name = name;
this.userGroup = userGroup;
this.lastLogin = lastLogin;
}
.....
}
These classes constitute the metamodel of your persistence context. They are used when you use the JPA2 Criteria API, in order to create type-safe queries, based on identifiers instead of Strings. For example:
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Person> query = builder.createQuery(Person.class);
Root<Person> from = query.from(Person.class);
query.where(criteriaBuilder.equal(person.get(Person_.name), "Doe"));
Using Person_.name instead of "name" guarantees that you're using a field that exists, and makes sure you'll get a compilation error instead of a runtime error if you rename the field name to lastName, for example.

JPA QueryException: The list of fields to insert into the table is empty

I actually have a problem with JPA. He is complaining about one
of my Entities:
javax.persistence.RollbackException: Exception [EclipseLink-6023] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.QueryException
Exception Description: The list of fields to insert into the table [DatabaseTable(TBL_SPJ_CAST_MOVIE)] is empty. You must define at least one mapping for this table.
After some researching i found out that this Exception appears when
there are no columns defined in the Entity classe because ofcourse
you cant insert Data into an empty Table.
However i have actually two columns defined in my Entity. One for the id
and one for a foreign key to a m:n table:
import java.io.Serializable;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
#Entity
#Table(name="TBL_SPJ_CAST_MOVIE")
public class CastMovie implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="CAST_MOVIE_ID", unique=true)
private int castID = 0;
#ManyToMany(fetch=FetchType.LAZY, cascade={CascadeType.ALL})
#JoinTable(name="TBL_SPJ_CAST_ROLE", joinColumns={#JoinColumn(name="CAST_MOVIE_ID")}, inverseJoinColumns={#JoinColumn(name="ROLE_ID")})
private List<Role> roles = null;
public CastMovie() {}
public int getCastID() {
return castID;
}
public void setCastID(int castID) {
this.castID = castID;
}
public List<Role> getRoles() {
return roles;
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
}
So whats the point of this Error? All Data coming from a xml file so i cant
put in more columns (if thats the problem).
EDIT:
Here is the structure of the four tables involved in this problem:
One Movie has one Cast -> Relationship One to One
Many Casts have many Rols -> Relationship Many to Many
I had the same problem.
Set the GenerationType of id field to GenerationType.TABLE and it will do the trick.
Also read this