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

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

Related

( 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.

How to select particular column from different Table using Spring Data JPA Join

I am trying to access particular column from different table using Spring Data JPA Inner Join.
I created four model. AccountModel is main model.
i used manyToOne mapping in AccountModel to the other three model(DepartmentModel,AccountCPCMappingModel,InvestigatorModel). I am trying to access particular column from four table using native Query in AccountRepository
This is my application scenario.
1.AccountModel.java
package com.demo.model;
import java.io.Serializable;
import java.sql.Timestamp;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
#Entity
#Table(name="account")
public class AccountModel implements Serializable {
private static final long serialVersionUID = 1L;
#Id
public Integer naccountid;
public String namount;
public String sacctdesc;
public Integer naccountcpcmappingid;
public Integer nindirectcostrate;
public Integer nagencyid ;
public Integer ndeptid ;
public String sgrantnum;
public Timestamp dstartdate;
public Timestamp denddate;
public String slocation;
public String sclientacctid;
public Integer ninvestigatorid;
public Integer ninstid;
public Integer ntempaccountid;
#ManyToOne(optional = true)
#JoinColumn(name="ndeptid",insertable = false, updatable = false)
public DepartmentModel department;
#ManyToOne(optional = true)
#JoinColumn(name="ninvestigatorid",insertable = false, updatable = false)
public InvestigatorModel investigator;
#ManyToOne(optional = false)
#JoinColumn(name="naccountcpcmappingid",insertable = false, updatable = false)
public AccountCPCMappingModel accountCPC;
//...Getter and Setter
}
2 DepartmentModel
package com.demo.model;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "department")
public class DepartmentModel implements Serializable {
private static final long serialVersionUID = 1L;
#Id
public Integer ndeptid;
public String sdeptname ;
public Integer ninstid ;
public Boolean bislocked;
public String sclientdeptid;
public Integer nsurveymethodid;
public Boolean bisjointuse;
public Integer ntempdeptid;
public Boolean balternatejointusepercentage;
public Integer ndivid;
//...Getter and Setter
3.InvestigatorModel
package com.demo.model;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name="investigator")
public class InvestigatorModel implements Serializable{
private static final long serialVersionUID = 1L;
#Id
public Integer ninvestigatorid;
public String sinvestigatorname;
public Integer ninstid ;
public String stitle;
public Integer ntempinvestigatorid;
public Integer nempid;
AccountRepository
package com.demo.repository;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import com.demo.model.AccountModel;
#Repository
public interface AccountRepository extends JpaRepository<AccountModel, Integer>{
#Query(value="select acct.sclientacctid,acct.sacctdesc,acct.slocation,invest.sinvestigatorname, \r\n" +
"dept.sclientdeptid,dept.sdeptname,acp.sccpcode \r\n" +
"from Account acct join Department dept on acct.nDeptID=dept.nDeptID \r\n" +
"join Investigator invest on acct.nInvestigatorID=invest.nInvestigatorID \r\n" +
"join AccountCPCMapping acp on acct.nAccountCPCMappingID=acp.nAccountCPCMappingID \r\n" +
"where acct.nInstID=60 \r\n" +
"order by acct.sclientacctid Asc",nativeQuery=true)
List<Object[]> findByNaccountid();
}
AccountService
package com.demo.services;
import java.util.List;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.demo.model.AccountModel;
import com.demo.repository.AccountRepository;
#Service
public class AccountService {
#Autowired
AccountRepository accRepo;
public List<AccountModel> findLocation()
{
return accRepo.findBySlocation();
}
public Set<Object[]> gridLoad()
{
Set<Object[]> gridObj=accRepo.findByNaccountid();
return gridObj;
}
}
AccountController
package com.demo.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.demo.model.AccountModel;
import com.demo.services.AccountService;
#RestController
#RequestMapping("/SpaceStudy/SpaceAdmin")
public class AccountController
{
#Autowired
AccountService accService;
#CrossOrigin(origins="*")
#GetMapping("/AccountMaintenance/LoadLocation")
public List<AccountModel> findLocation()
{
return accService.findLocation();
}
#CrossOrigin(origins="*")
#PostMapping("/AccountMaintenance/LoadGrid")
public Set<Object[]> GridLoad()
{
return accService.gridLoad();
}
}
I am getting output in this format
But I want output in JSON Format like this (key,value pairs)
sample output
[
{
"userId": 1,
"id": 1
}
]
Can any one help me what i need to change in my code for json data.
Your query should return List<Object[]> and not List<AccountModel>.
JPA equivalent query will be something like this.
Query("select acct.sclientacctid,acct.sacctdesc,acct.slocation,invest.sinvestigatorname, dept.sclientdeptid,dept.sdeptname,acp.sccpcode
from AccountModel acct join acct.department dept join acct.investigator invest join acct.accountCPC acp
where acct.nInstID= :instId
order by acct.sclientacctid")
List<Object[]> findByInstId (#Param("instId") Integer instId);
This will return you a List of Object array and the array will have the columns in order it appears in the select. Give it a try.

FindBy method returnign all records in PagingAndSortingRepository

Im using a findBy method in a interface that extends PagingAndSortingRepository. This method is:
public List<MyType> findByClassification(String classification);
When I invoke this method (myObject.findByClassification("A")), it returns all values and not only records filtered by classification "A".
The class model:
package mypackage;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "mytype")
public class MyType implements Serializable {
private static final long serialVersionUID = 1L;
#Id
private Integer id;
private String name;
private String classification;
//getters and setters
}
Other find methods work fine:
findByClassificationAndName_StartingWith
findByName
These methods return only filtered records and not all records in table.
Any idea?
Thanks!