Spring boot JPA nnotationException: No identifier specified for entity, while having proper id - spring-data-jpa

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.

Related

Auto generated String type #Id in Spring Boot to connect mongo

I am incrementing my Autogenerated Id value but I need String type
.This is my service class:
package com.stackroute.orderhistory.service;
import com.stackroute.orderhistory.model.AutogenerateId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import java.util.Objects;
import static org.springframework.data.mongodb.core.FindAndModifyOptions.options;
#Service
public class SequenceGeneratorService {
#Autowired
private MongoOperations mongoOperations;
public String getSequenceNumber(String sequenceName){
Query query=new Query(Criteria.where("order_id").is(sequenceName));
Update update=new Update().inc("seq",1);
AutogenerateId counter = mongoOperations
.findAndModify(query,
update, options().returnNew(true).upsert(true),
AutogenerateId.class);
return !Objects.isNull(counter) ? counter.getSeq() : "1";
}
}
.This is my Entity Class :
import lombok.*;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Transient;
import org.springframework.data.mongodb.core.mapping.Document;
#NoArgsConstructor
#ToString
#AllArgsConstructor
#Getter
#Setter
#Document(collection = "orders")
public class OrderHistoryModel {
#Transient
public static final String SEQUENCE_NAME="Ordersequence";
#Id
private String orderId;
private String productName;
private int orderAmount;
private String orderPlaced;
private String orderStatus;
private String paymentMethod;
private String shippingAddress;
}
.This is my AutoGenerated Entity class :
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
#Document(collection = "db_sequence")
#Data
#AllArgsConstructor
#NoArgsConstructor
public class AutogenerateId {
#Id
private String id;
private String seq;
}
In this Code I am getting Order_Id as 1,2,3 and so on (In Postman)
But I need Order_Id like order1, order2, order3 and so on...
Please help me out.
In my case, I didn't customise the auto-generation of the id, instead:
in my entity i just annotated the id by #Id s follow:
the DTO:
and here's my service :
the method dtoToUser:
and mongodb will generate a random and unique UUID for me, as follow:
So, Use IDs provided by MongoDB, which are more or less universally unique

( Solved ) How to join "#joinTable" using QueryDSL

I want to get the SQL to join Summoner, summoner_match and match using JPASQLQuery class.
like this.
SELECT
*, row_number()OVER()
FROM
summoner s
LEFT OUTER JOIN
summoner_match sm
on
s.account_id= sm.account_id
LEFT OUTER JOIN
match m
on
sm.game_id = m.game_id
I add my source code below.
package gg.om.omgg.domain.summoner;
import gg.om.omgg.domain.match.Match;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
#Getter
#NoArgsConstructor
#Entity
public class Summoner implements Serializable {
#Id#Column(length=56)
private String id;
#Column(name="account_id", length=56)
private String accountId;
private int profileIconId;
private long revisionDate;
private String name;
#Column(length=78)
private String puuid;
private long summonerLevel;
#OneToMany
#JoinTable(name="summoner_match",
joinColumns = #JoinColumn(name="account_id"),
inverseJoinColumns = #JoinColumn(name="game_id")
)
private List<Match> matches = new ArrayList<>();
//...
}
package gg.om.omgg.domain.match;
import gg.om.omgg.domain.participant.Participant;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
#Getter
#NoArgsConstructor
#Entity
public class Match {
#Id
#Column(name="game_id")
private long gameId;
private int queueId;
private String platformId;
private int seasonId;
private long gameCreation;
private long gameDuration;
#OneToMany
#JoinColumn(name = "game_id", referencedColumnName = "game_id")
List<Participant> participants = new ArrayList<>();
//...
}
.
.
.
Seems to have found a way.
I will be an advisor.
package gg.om.omgg.domain.summoner;
import com.querydsl.core.Tuple;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.querydsl.jpa.sql.JPASQLQuery;
import com.querydsl.sql.SQLExpressions;
import gg.om.omgg.domain.match.QMatch;
import gg.om.omgg.domain.participant.QParticipant;
import gg.om.omgg.web.dto.SummonerIntegrationInformationResponseDTO;
import lombok.RequiredArgsConstructor;
#RequiredArgsConstructor
public class SummonerCustomRepositoryImpl implements SummonerCustomRepository {
// JPASQLQuery class is registered as #Bean in advance
private final JPASQLQuery jpasqlQuery;
#Override
public void mySolution() {
QSummoner summoner = QSummoner.summoner;
QMatch match = QMatch.match;
// Create Qclass for #JoinTable
QSummoner summoner_match1 = new QSummoner("summoner_match");
QMatch summoner_match2 = new QMatch("summoner_match");
jpasqlQuery
.select(summoner, match, SQLExpressions.rowNumber().over())
.from(summoner)
.leftJoin(summoner_match1)
.on(summoner.accountId.eq(summoner_match1.accountId))
.leftJoin(match).on(summoner_match2.gameId.eq(match.gameId))
.fetch();
}
}

java.util.ArrayList cannot be cast to class [Ljava.lang.Object; <springboot test>

I'm currently testing my JPA #Query and keep getting this error
<br>
class java.util.ArrayList cannot be cast to class [Ljava.lang.Object; (java.util.ArrayList and [Ljava.lang.Object; are in module java.base of loader 'bootstrap')
<br>
Member Entity
package org.morgorithm.frames.entity;
import com.sun.istack.Nullable;
import lombok.*;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Entity
#Builder
#AllArgsConstructor
#NoArgsConstructor
#Getter
#ToString
public class Member {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long mno;
private String name;
private String phone;
}
Status Entity
package org.morgorithm.frames.entity;
import com.sun.istack.Nullable;
import lombok.*;
import javax.persistence.*;
#Entity
#Builder
#AllArgsConstructor
#NoArgsConstructor
#Getter
#ToString(exclude={"member","facility"})
public class Status extends BaseEntity{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long statusnum;
#ManyToOne(fetch=FetchType.LAZY)
private Member member;
#ManyToOne(fetch=FetchType.LAZY)
private Facility facility;
private double temperature;
private Boolean state;
}
MemberRepository
package org.morgorithm.frames.repository;
import org.morgorithm.frames.entity.Member;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;
public interface MemberRepository extends JpaRepository<Member,Long> {
#Query("select m, s from Member m left join Status s ON s.member=m WHERE m.mno=:mno")
List<Object[]> getMemberWithStatus(#Param("mno") Long mno);
}
what I want to test is that #Query part.
so I made a test file as below
MemberRepositoryTests
package org.morgorithm.frames.repository;
import org.junit.jupiter.api.Test;
import org.morgorithm.frames.entity.Member;
import org.morgorithm.frames.entity.MemberImage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Commit;
import org.springframework.transaction.annotation.Transactional;
import java.util.Arrays;
import java.util.UUID;
import java.lang.Object;
import java.util.stream.IntStream;
#SpringBootTest
public class MemberRepositoryTests {
#Autowired
private MemberRepository memberRepository;
#Autowired
private MemberImageRepository memberImageRepository;
#Test
public void testGetMemberByMno(){
Object result=memberRepository.getMemberWithStatus(100L);
Object[] arr=(Object[])result;
System.out.println("----------------------------*************************");
System.out.println(Arrays.toString(arr));
System.out.println("===================================");
}
}
I want to test this getMemberWithStatus method
but getting those error above..
I think the problem is
Object[] arr=(Object[])result; this part
what did I do wrong??
oh and for your information I did put some test data into DB
solve the problem by changing my code as below.
#Test
public void testGetMemberByMno(){
List<Object[]> result=memberRepository.getMemberWithStatus(100L);
List<Object> arr=Arrays.asList(result);
for(Object[] a:result){
System.out.println(Arrays.toString(a));
}
}

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.

JPA Repository not working properly

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.