java.lang.IllegalArgumentException with java persistance API - spring

I am getting a java.lang.IllegalArgumentException similar to the link given below.To solve it I tried to change the field type from Integer to Long. But still I am getting:
Caused by: java.lang.IllegalArgumentException: Parameter value [5] was not matching type [com.buddhiedge.server.entity.StudyplanCategory]
StudyplanCategory is the entity class.
The problem is similar to the one in the below link.
Hibernate - Parameter value [2011] was not matching type [java.lang.Integer]. How to solve?
My entity Class is:
#JsonIgnoreProperties({ "studyplanCategoryList", "dropboxzipfile",
"parentCategory", "createdDate", "updatedDate" })
#JsonPropertyOrder({ "id", "name", "status", "sptTutorialsList" })
#Entity
#Table(name = "studyplan_category", catalog = "buddhiedgeserver_db", schema = "", uniqueConstraints = { #UniqueConstraint(columnNames = { "dropboxzipfile" }) })
#NamedQueries({
#NamedQuery(name = "StudyplanCategory.findSubStudyPlanById", query = "SELECT s FROM StudyplanCategory s WHERE s.parentCategory=:parentCategory order by updatedDate DESC")})
public class StudyplanCategory implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#NotNull
#Column(name = "id", nullable = false)
private Long id;
}

It seems you are passing 5 as parameter to the query. If you want to pass an ID rather than an entity, change the query to:
WHERE s.parentCategory.id=:parentCategoryId

Related

Criteria API Specification - Filter records and return only the latest record for many to one mappings

I have two tables, Lead and LeadActivity. A lead can have many lead activities and mapping is done as #ManyToOne form LeadActivity to Lead.
Problem Statement -I want to to filter LeadActivity records such that, If there are more than one leadactivity records with same leadId, i should get only one record which is latest (have max primary key). Can anyone guide me on how to write specification or criteria API in such situations? I know this can be achieved through other ways but I have to use specification API. Below are the entity classes
Lead
#Entity
#Table(name = "customer_lead")
#Where(clause = ReusableFields.SOFT_DELETED_CLAUSE)
#Audited(withModifiedFlag = true)
#Data
public class Lead extends ReusableFields implements Serializable
{
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "lead_id", updatable = false, nullable = false)
Long leadId;
#Column(name = "name")
String customerName;
#Column(name = "primary_mobile")
String primaryMobile;
#Column(name = "secondary_mobile")
String secondaryMobile;
//more fields
}
Lead Activity
#Entity
#Table(name = "LeadActivity")
#Data
#Where(clause = ReusableFields.SOFT_DELETED_CLAUSE)
public class LeadActivity extends ReusableFields implements Serializable
{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "leadactivity_id", updatable = false, nullable = false)
Long leadActivityId;
#Column(name = "activity_date_time", nullable = false)
#NonNull
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm")
Date activityDateTime;
#Column(name = "title")
#NonNull
String title;
#OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinColumn(name = "lead_id", nullable = false)
#JsonIgnoreProperties(
{ "hibernateLazyInitializer", "handler" })
#NotFound(action = NotFoundAction.IGNORE)
Lead lead;
//More fields
}
Expected Output - Suppose there are two records present with same leadId. I want to fetch only the latest among them based on their id. One with lower id should be ignored
Try this:
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<LeadActivity> cq = cb.createQuery(LeadActivity.class);
Root<LeadActivity> rootLeadActivity = cq.from(LeadActivity.class);
Join<LeadActivity,Lead> joinLead = rootLeadActivity.join(LeadActivity_.lead,JoinType.INNER);
/* If you dont use metamodel:
* Join<LeadActivity,Lead> joinLead = rootLeadActivity.join("lead",JoinType.INNER);
*/
// For performance, if you use JPA 2.1 set the leader id condition in the join
joinLead.on(cb.equal(joinLead.get(Lead_.leadId),LEAD_ID));
List<Predicate> predicatesList= new ArrayList<>();
/* if you use version 2.0 you will have to put it in the where
* predicatesList.add(cb.equal(joinLead.get(Lead_.leadId),LEAD_ID));
*/
Subquery<Long> sqMaxId = cq.subquery(Long.class);
Root<LeadActivity> sqRootActivity = sqMaxId.from(LeadActivity.class);
Join<LeadActivity,Lead> sqJoinLead = sqRootActivity.join(LeadActivity_.lead,JoinType.INNER);
sqMaxId.where(cb.equal(sqJoinLead.get(Lead_.leadId),joinLead.get(Lead_.leadId)));
sqMaxId.select(cb.max(sqRootActivity.get(LeadActivity_.leadActivityId)));
predicatesList.add(cb.equal(rootLeadActivity.get(LeadActivity_.leadActivityId),sqMaxId.getSelection()));
cq.where(predicatesList.toArray(new Predicate[predicatesList.size()]));
cq.multiselect(rootLeadActivity);
The result query:
select a.* from lead_activity a
inner join lead l on a.lead_id = l.lead_id and l.lead_id = LEAD_ID
where a.lead_activity_id =
(select max(lead_activity_id) from lead_activity where lead_id = LEAD_ID)

composite pattern, I am not able to retrieve all entities from the backend

I am trying to implement and use the composite pattern in my system.
The problem is that I cant retrieve all the hierarchy of entities from the backend.
I am not sure what is the problem, the fetch is fine. So, I am not sure if is hibernate.
Lets see, these are my entities.
#Entity
#Table(name = "game")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
#Document(indexName = "game")
public class Game extends AbstractAuditingEntity implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#NotNull
#Column(name = "name", nullable = false)
private String name;
#Column(name = "detail")
private String detail;
#OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinColumn(name = "rule_id")
private GameRule gameRule;
...
In this class I save the main "GameRule"
#Entity
#Table(name = "game_rule")
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING)
#DiscriminatorValue("rule")
#JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "_class")
#JsonSubTypes({
#JsonSubTypes.Type(value = SimpleRule.class, name = "SimpleRule"),
#JsonSubTypes.Type(value = CompositeRule.class, name = "CompositeRule") })
public abstract class GameRule implements Serializable {
private static final long serialVersionUID = -4597791997254248990L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id", nullable = false)
private Long id;
private String operator;
In this class I save a list of GameRules
#Entity
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(discriminatorType = DiscriminatorType.STRING)
#DiscriminatorValue("group")
public class CompositeRule extends GameRule {
private static final long serialVersionUID = 6197786758476721324L;
#ManyToMany(fetch = FetchType.EAGER, cascade = { CascadeType.ALL })
#JoinTable(name = "game_rules_hierarchy",
joinColumns = #JoinColumn(name = "parent_rule_id", referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(name = "child_rule_id", referencedColumnName = "id"))
#OrderBy("id")
private List<GameRule> rules;
public List<GameRule> getRules() { return rules; }
public void setRules(List<GameRule> rules) { this.rules = rules; }
And now the leaf entity.
#Entity
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(discriminatorType = DiscriminatorType.STRING)
#DiscriminatorValue("simple")
public class SimpleRule extends GameRule {
private static final long serialVersionUID = 6197786758476721324L;
private String variable;
private Double value;
#ManyToOne
#NotNull
private Device device;
Now, the restController to retrieve the data
#RequestMapping(value = "/games/{id}",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
#Timed
#Transactional
public ResponseEntity<Game> getGame(#PathVariable Long id) {
log.debug("REST request to get Game : {}", id);
Game game = gameRepository.findOne(id);
return Optional.ofNullable(game)
.map(result -> new ResponseEntity<>(
result,
HttpStatus.OK))
.orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND));
}
Now in the view I am able to receive the CompositeRule objects but nothing about the simpleRule objects.
From the UI (angular), I am using this JSON to load the hierarchy.
vm.game.gameRule = {id: null, operator: "", type:null, _class:"CompositeRule",
rules: [ {id: null, operator: "", type:null, _class:"CompositeRule", rules:
[{id: null, type:null, _class:"SimpleRule", device: "6", variable: "POWER", operator: ">", value: "100"},
{id: null, type:null, _class:"SimpleRule", device: "6", variable: "POWER", operator: ">", value: "100"}]}
]};
This is loaded succesfully in the DB. But the problem is when I try to retrieve the entire hierarchy. Currently I am receiving only the CompositeRule objects, somthing like:
vm.game.gameRule = {id: 1, operator: "", type:null, _class:"CompositeRule",
rules: [ {id: 2, operator: "", type:null, _class:"CompositeRule", rules:[]} ]};]
In the RestController I am able to see all the hierarchy objects. I am not sure what the problem is.
Thanks for reading.
MY BAD!
Everything was fine. My problem is in the console logs. It seems that the console in chrome is not showing all the hierarchy. But if I go to the network view I am able to see everything.
Thanks.

Add entity with OneToOne Relation using JPA and REST

I am using Spring JPA Restful, and I don't understand how to insert an entity with a foreign key.
Activity Entity:
#Entity
#Table(name= "Activity")
public class Activity implements Serializable{
#Id
#GeneratedValue(generator = "uuid")
#GenericGenerator(name="uuid", strategy = "uuid2")
#Column(name = "uuid", nullable = false, unique = true)
private UUID uuid;
#OneToOne(fetch = FetchType.EAGER, cascade=CascadeType.MERGE)
#JoinColumn(name="type", nullable = false)
private ActivityType type;
#Column(nullable = false)
private String label;
ActivityType Entity:
#Entity
#Table(name= "ActivityType")
public class ActivityType implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#Column(nullable = false, unique = true)
private String code;
#Column(nullable = false
private String label;
Is it possible to insert Activity simply? With something like this JSON where ActivityType's id "1" exists:
createActivity:
{"label":"LABEL","type":1}
With this code I have to do:
createActivity:
{"label":"LABEL","type":{"id":1}}
which return value is:
{
"uuid": "a54b27aa-8d49-41fd-8976-70c019c40e3b",
"type": {
"id": 1,
"code": null,
"label": null
},
"label": "LABEL",
"details": null
}
I use the library gson for parsing domain classes into JSON.
//... code for making your activity, let's say you have an Activity object myActivity
Just add the following code where you want to parse your object into JSON.
Gson gson = new GSON();
String json = gson.toJson(myActivity);

Spring mapping using hibernate

I am joining two table using one to many relationship
my first table is role and second is roleCompany. where role_id is reference key in roleCompany table.
But when I am writting query to get all companies for specific id it showing me following error
SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/myproject] threw exception [Request processing failed; nested exception is org.hibernate.PropertyAccessException: could not get a field value by reflection getter of com.test.myproject.domain.entity.RoleEntity.id] with root cause
java.lang.IllegalArgumentException: Can not set java.lang.Long field com.test.myproject.domain.entity.RoleEntity.id to java.lang.Long
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58)
at sun.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:36)
My RoleEntity Class is :
#Entity
#Table(name = "roles")
public class RoleEntity {
#Id
#Getter
#Setter
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", unique = true, nullable = false)
private Long id;
#Getter
#Setter
#Column(name = "role", nullable = false)
private String role;
#Getter
#Setter
#OneToMany(mappedBy = "roles")
List<RoleCompanyEntity> companyentities;
}
and my RoleCompanyEntity is
#NamedQueries({
#NamedQuery(name = RoleCompanyEntity.FIND_ROLE_COMPANY_BY_ROLE_ID, query = "select r.companyId, r.companyName from RoleCompanyEntity r where r.roles =:roleId")
})
#Entity
#Table(name = "role_company")
public class RoleCompanyEntity {
public static final String FIND_ROLE_COMPANY_BY_ROLE_ID = "findRoleCompanyByRoleId";
#Id
#Getter
#Setter
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "company_id", unique = true, nullable = false)
private Long companyId;
#Getter
#Setter
#Column(name = "company_name", unique = true, nullable = false)
private String companyName;
#Getter
#Setter
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name="role_id", nullable=false)
private RoleEntity roles;
}

How do I write this JPA query that requires a JOIN?

I'm using JPA 2.0, Hibernate 4.1.0.Final, and Spring 3.1.1.RELEASE. I have two entities:
#Entity
#Table(name = "user",
uniqueConstraints = { #UniqueConstraint(columnNames = { "USER_NAME" }) }
)
public class User implements Comparable<User>, Serializable
{
...
#Column(name = "first_name")
#NotNull
/* the first name of the User */
private String firstName;
and
#Entity
#Table(name="code_user",
uniqueConstraints = {
#UniqueConstraint(columnNames = { "SAMPLE_WORD_ID", "USER_ID" }) }
)
public class CodeUser
{
#Id
#NotNull
#GeneratedValue(generator = "uuid-strategy")
#Column(name = "ID")
private String id;
#ManyToOne
#JoinColumn(name = "CODE_ID", nullable = false, updatable = true)
private Code code;
#ManyToOne
#JoinColumn(name = "USER_ID", nullable = false, updatable = true)
private User user;
How do I write a JPA/CriteriaBuilder query to find all User objects who's first name matches "Dave" and who are tied to a Code record in which the code is "abode"?
I might have missed an HQL syntax element
SELECT user FROM CodeUser codeUser
JOIN FETCH codeUser.user user
JOIN FETCH codeUser.code code
WHERE user.firstName = 'Dave' AND code.value = 'abode'
assuming Code has a field value holding the value "abode". You might not need the FETCH.
You can always replace the literal values with a placeholder like ? or a named placeholder like :name and set their values from the Query object.

Resources