Count number of Item using Hibernate/JPA or JdbcTemplate - spring

I am new to Spring/Hibernate/JPA. I have an entity class MovieEntity and MovieVersionEntity. MovieEntity has few details about the movie (like genre of movie) but MovieVersionEntity has more details about it (name, director...). So I want to count the number of movies (MovieVersionEntity) associated to the MovieEntity for the given type.
MovieEntity:
#Entity(name="MovieEntity")
#Table(name="Movie")
public class MovieEntity {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="Id")
private long id;
#Column(name="IsDeleted")
private boolean isDeleted;
#Column(name="ModifiedDate")
#Temporal(TemporalType.TIMESTAMP)
private Date modifiedDate;
#OneToOne()
#JoinColumn(name="MovieTypeId")
private MovieTypeEntity movieTypeEntity;
#OneToMany(mappedBy="movieEntity",optional = false)
private List<MovieVersionEntity> movieVersionEntity;
#Transient
//#Formula("select count(*) from movie_version mv where mv.id=id")
private int childCount;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public boolean isDeleted() {
return isDeleted;
}
public void setDeleted(boolean isDeleted) {
this.isDeleted = isDeleted;
}
public MovieTypeEntity getMovieTypeEntity() {
return movieTypeEntity;
}
public void setMovieTypeEntity(MovieTypeEntity movieTypeEntity) {
this.movieTypeEntity = movieTypeEntity;
}
public Date getModifiedDate() {
return modifiedDate;
}
public void setModifiedDate(Date modifiedDate) {
this.modifiedDate = modifiedDate;
}
public MovieVersionEntity getMovieVersionEntity() {
return movieVersionEntity;
}
public void setMovieVersionEntity(MovieVersionEntity movieVersionEntity) {
this.movieVersionEntity = movieVersionEntity;
}
public int getChildCount() {
return childCount;
}
public void setChildCount(int childCount) {
this.childCount = childCount;
}
}
MovieVersionEntity
#Entity(name = "MovieVersionEntity")
#Table(name="MovieVersion")
//#EntityListeners(AuditingEntityListener.class)
public class MovieVersionEntity {
#Id()
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="MovieId")
private long movieId;
#NotBlank
#Column(name="MovieName")
private String movieName;
#NotBlank
#Column(name="DirectorName")
private String directorName;
#NotBlank
#Column(name="Description")
private String description;
#Column(name="StopDate")
#Temporal(TemporalType.TIMESTAMP)
private Date stopDate;
#Column(name="DoneWatching")
private boolean doneWatching;
#Column(name="WatchDate")
#Temporal(TemporalType.TIMESTAMP)
//#CreatedDate
private Date watchDate;
#Column(name="ModifiedDate")
#Temporal(TemporalType.TIMESTAMP)
//#LastModifiedDate
private Date modifiedDate;
#ManyToOne(optional = false)
#JoinColumn(name="Id")
private MovieEntity movieEntity;
public String getMovieName() {
return movieName;
}
public void setMovieName(String movieName) {
this.movieName = movieName;
}
public String getDirectorName() {
return directorName;
}
public void setDirectorName(String directorName) {
this.directorName = directorName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Date getStopDate() {
return stopDate;
}
public void setStopDate(Date stopDate) {
this.stopDate = stopDate;
}
public boolean isDoneWatching() {
return doneWatching;
}
public void setDoneWatching(boolean doneWatching) {
this.doneWatching = doneWatching;
}
public Date getWatchDate() {
return watchDate;
}
public void setWatchDate(Date watchDate) {
this.watchDate = watchDate;
}
public Date getModifiedDate() {
return modifiedDate;
}
public void setModifiedDate(Date modifiedDate) {
this.modifiedDate = modifiedDate;
}
public long getMovieId() {
return movieId;
}
public void setMovieId(long movieId) {
this.movieId = movieId;
}
public MovieEntity getMovieEntity() {
return movieEntity;
}
public void setMovieEntity(MovieEntity movieEntity) {
this.movieEntity = movieEntity;
}
}
I have written a query but I am getting sql error for it
#Query(value = "select m.*, ct.ChildCount" +
"from (" +
"select mv.id, count(movie_id) as ChildCount " +
"from movie_version mv " +
"group by mv.id" +
") as ct join movie m " +
"on ct.id = m.id;",nativeQuery = true)
List<MovieEntity> getMoviesWithCount();
Error
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'select mv.id, count(movie_id) as ChildCount from movie_version mv group by mv.id' at line 1
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_60]
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_60]
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_60]
at java.lang.reflect.Constructor.newInstance(Constructor.java:422) ~[na:1.8.0_60]
at com.mysql.jdbc.Util.handleNewInstance(Util.java:425) ~[mysql-connector-java-5.1.44.jar:5.1.44]
at
Also, I am not sure if this is a right way to do it. Is there any other way I can save the count in the Transient variable. I tried using #Formuala too, but that does not give me 0 count.
Formula:
#Formula("select count(*) from movie_version mv where mv.id=id")
This is the first time I am dealing with Transient variable and I am not sure how it maps to the entity if its not persisted in the db.

However, #Formula worked for me. #Transient and #Formula cannot go together. #Formula is read only so I do not have to worry about the data being persisted.
http://outbottle.com/hibernate-populating-an-unmapped-entity-field-with-count-using-formula/

Related

springdatarepository ElasticSearch works on save but fails on update with java.lang.StackOverflowError: null

I am getting java.lang.StackOverflowError: null when updating my data through springdataelasticsearch. The application was generated using Jhipster 7.0.1. Spring Boot version is 2.4.4.. It works fine when creating a new object but an update results in error. Here is the relevant portion of CountryAdminUnitTypeService.java.
* Save a countryAdminUnitType.
*
* #param countryAdminUnitType the entity to save.
* #return the persisted entity.
*/
public CountryAdminUnitType save(CountryAdminUnitType countryAdminUnitType) {
log.debug("Request to save CountryAdminUnitType : {}", countryAdminUnitType);
CountryAdminUnitType result = countryAdminUnitTypeRepository.save(countryAdminUnitType);
countryAdminUnitTypeSearchRepository.save(result);
return result;
}
When creating, here's how the object looks on call to countryAdminUntiTypeSearchRepository.save(result);.
result = {CountryAdminUnitType#23268} "CountryAdminUnitType{id=200102, name='Province'}"
id = {Long#23292} 200102
name = "Province"
parent = null
country = {Country#23275} "Country{id=183778, name='Turkey', isoCode='TR'}"
id = {Long#23281} 183778
name = "Turkey"
isoCode = "TR"
countryAdminUnitTypes = null
And here's how it looks on updating.
result = {CountryAdminUnitType#24746} "CountryAdminUnitType{id=200102, name='Province'}"
id = {Long#24752} 200102
name = "Province"
parent = null
country = {Country#24754} "Country{id=183778, name='Turkey', isoCode='TR'}"
id = {Long#24756} 183778
name = "Turkey"
isoCode = "TR"
countryAdminUnitTypes = {PersistentSet#24761} size = 1
0 = {CountryAdminUnitType#24746} "CountryAdminUnitType{id=200102, name='Province'}"
id = {Long#24752} 200102
name = "Province"
parent = null
country = {Country#24754} "Country{id=183778, name='Turkey', isoCode='TR'}"
The only difference I see is that countryAdminUnitTypes is not null in second case. However this should be taken care of by JsonIgnoreProperties given in Country.java below.
Here's the beginning of a very long log file.
ERROR 91444 --- [ XNIO-5 task-1] c.s.c.s.CountryAdminUnitTypeService : Exception in save() with cause = 'NULL' and exception = 'null'
java.lang.StackOverflowError: null
at org.springframework.data.util.Streamable.stream(Streamable.java:87)
at org.springframework.data.util.Streamable.lambda$map$1(Streamable.java:101)
at org.springframework.data.util.LazyStreamable.stream(LazyStreamable.java:55)
at org.springframework.data.util.LazyStreamable.iterator(LazyStreamable.java:46)
at java.base/java.lang.Iterable.forEach(Iterable.java:74)
at org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter.writeCollectionValue(MappingElasticsearchConverter.java:710)
at org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter.getWriteComplexValue(MappingElasticsearchConverter.java:620)
at org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter.writeProperty(MappingElasticsearchConverter.java:601)
at org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter.writeProperties(MappingElasticsearchConverter.java:553)
at org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter.writeEntity(MappingElasticsearchConverter.java:511)
at org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter.writeEntity(MappingElasticsearchConverter.java:636)
at org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter.getWriteComplexValue(MappingElasticsearchConverter.java:627)
at org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter.writeProperty(MappingElasticsearchConverter.java:601)
at org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter.writeProperties(MappingElasticsearchConverter.java:553)
at org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter.writeEntity(MappingElasticsearchConverter.java:511)
at org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter.writeEntity(MappingElasticsearchConverter.java:636)
at org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter.getWriteComplexValue(MappingElasticsearchConverter.java:627)
at org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter.lambda$writeCollectionValue$7(MappingElasticsearchConverter.java:709)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
at java.base/java.util.Spliterators$IteratorSpliterator.tryAdvance(Spliterators.java:1812)
at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.lambda$initPartialTraversalState$0(StreamSpliterators.java:294)
at java.base/java.util.stream.StreamSpliterators$AbstractWrappingSpliterator.fillBuffer(StreamSpliterators.java:206)
at java.base/java.util.stream.StreamSpliterators$AbstractWrappingSpliterator.doAdvance(StreamSpliterators.java:161)
at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.tryAdvance(StreamSpliterators.java:300)
at java.base/java.util.Spliterators$1Adapter.hasNext(Spliterators.java:681)
at java.base/java.lang.Iterable.forEach(Iterable.java:74)
at org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter.writeCollectionValue(MappingElasticsearchConverter.java:710)
at org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter.getWriteComplexValue(MappingElasticsearchConverter.java:620)
at org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter.writeProperty(MappingElasticsearchConverter.java:601)
at org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter.writeProperties(MappingElasticsearchConverter.java:553)
at org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter.writeEntity(MappingElasticsearchConverter.java:511)
at org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter.writeEntity(MappingElasticsearchConverter.java:636)
at org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter.getWriteComplexValue(MappingElasticsearchConverter.java:627)
at org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter.writeProperty(MappingElasticsearchConverter.java:601)
at org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter.writeProperties(MappingElasticsearchConverter.java:553)
at org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter.writeEntity(MappingElasticsearchConverter.java:511)
at org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter.writeEntity(MappingElasticsearchConverter.java:636)
at org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter.getWriteComplexValue(MappingElasticsearchConverter.java:627)
at org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter.lambda$writeCollectionValue$7(MappingElasticsearchConverter.java:709)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
at java.base/java.util.Spliterators$IteratorSpliterator.tryAdvance(Spliterators.java:1812)
at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.lambda$initPartialTraversalState$0(StreamSpliterators.java:294)
at java.base/java.util.stream.StreamSpliterators$AbstractWrappingSpliterator.fillBuffer(StreamSpliterators.java:206)
at java.base/java.util.stream.StreamSpliterators$AbstractWrappingSpliterator.doAdvance(StreamSpliterators.java:161)
at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.tryAdvance(StreamSpliterators.java:300)
at java.base/java.util.Spliterators$1Adapter.hasNext(Spliterators.java:681)
at java.base/java.lang.Iterable.forEach(Iterable.java:74)
Here are the model classes.
CountryAdminUnitType.java
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import java.io.Serializable;
import javax.persistence.*;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.springframework.data.elasticsearch.annotations.FieldType;
/**
* A CountryAdminUnitType.
*/
#Entity
#Table(name = "country_admin_unit_type")
#Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
#org.springframework.data.elasticsearch.annotations.Document(indexName = "countryadminunittype")
public class CountryAdminUnitType implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
#SequenceGenerator(name = "sequenceGenerator")
private Long id;
#Column(name = "name")
private String name;
#ManyToOne
#JsonIgnoreProperties(value = { "parent", "country" }, allowSetters = true)
private CountryAdminUnitType parent;
#ManyToOne
#JsonIgnoreProperties(
value = { "defaultResidenceMeasurementUnit", "countryAdminUnitTypes", "preferences", "personNationalities" },
allowSetters = true
)
private Country country;
// jhipster-needle-entity-add-field - JHipster will add fields here
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public CountryAdminUnitType id(Long id) {
this.id = id;
return this;
}
public String getName() {
return this.name;
}
public CountryAdminUnitType name(String name) {
this.name = name;
return this;
}
public void setName(String name) {
this.name = name;
}
public CountryAdminUnitType getParent() {
return this.parent;
}
public CountryAdminUnitType parent(CountryAdminUnitType countryAdminUnitType) {
this.setParent(countryAdminUnitType);
return this;
}
public void setParent(CountryAdminUnitType countryAdminUnitType) {
this.parent = countryAdminUnitType;
}
public Country getCountry() {
return this.country;
}
public CountryAdminUnitType country(Country country) {
this.setCountry(country);
return this;
}
public void setCountry(Country country) {
this.country = country;
}
// jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here
#Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof CountryAdminUnitType)) {
return false;
}
return id != null && id.equals(((CountryAdminUnitType) o).id);
}
#Override
public int hashCode() {
// see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/
return getClass().hashCode();
}
// prettier-ignore
#Override
public String toString() {
return "CountryAdminUnitType{" +
"id=" + getId() +
", name='" + getName() + "'" +
"}";
}
}
Country.java
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.*;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.springframework.data.elasticsearch.annotations.FieldType;
/**
* A Country.
*/
#Entity
#Table(name = "country")
#Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
#org.springframework.data.elasticsearch.annotations.Document(indexName = "country")
public class Country implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
#SequenceGenerator(name = "sequenceGenerator")
private Long id;
#Column(name = "name")
private String name;
#Column(name = "iso_code")
private String isoCode;
#OneToMany(mappedBy = "country")
#Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
#JsonIgnoreProperties(value = { "parent", "country" })
private Set<CountryAdminUnitType> countryAdminUnitTypes = new HashSet<>();
// jhipster-needle-entity-add-field - JHipster will add fields here
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Country id(Long id) {
this.id = id;
return this;
}
public String getName() {
return this.name;
}
public Country name(String name) {
this.name = name;
return this;
}
public void setName(String name) {
this.name = name;
}
public String getIsoCode() {
return this.isoCode;
}
public Country isoCode(String isoCode) {
this.isoCode = isoCode;
return this;
}
public void setIsoCode(String isoCode) {
this.isoCode = isoCode;
}
public Set<CountryAdminUnitType> getCountryAdminUnitTypes() {
return this.countryAdminUnitTypes;
}
public Country countryAdminUnitTypes(Set<CountryAdminUnitType> countryAdminUnitTypes) {
this.setCountryAdminUnitTypes(countryAdminUnitTypes);
return this;
}
public Country addCountryAdminUnitType(CountryAdminUnitType countryAdminUnitType) {
this.countryAdminUnitTypes.add(countryAdminUnitType);
countryAdminUnitType.setCountry(this);
return this;
}
public Country removeCountryAdminUnitType(CountryAdminUnitType countryAdminUnitType) {
this.countryAdminUnitTypes.remove(countryAdminUnitType);
countryAdminUnitType.setCountry(null);
return this;
}
public void setCountryAdminUnitTypes(Set<CountryAdminUnitType> countryAdminUnitTypes) {
if (this.countryAdminUnitTypes != null) {
this.countryAdminUnitTypes.forEach(i -> i.setCountry(null));
}
if (countryAdminUnitTypes != null) {
countryAdminUnitTypes.forEach(i -> i.setCountry(this));
}
this.countryAdminUnitTypes = countryAdminUnitTypes;
}
// jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here
#Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof Country)) {
return false;
}
return id != null && id.equals(((Country) o).id);
}
#Override
public int hashCode() {
// see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/
return getClass().hashCode();
}
// prettier-ignore
#Override
public String toString() {
return "Country{" +
"id=" + getId() +
", name='" + getName() + "'" +
", isoCode='" + getIsoCode() + "'" +
"}";
}
}
This is because of how JHipster sets up save. It was only happening on updating objects with bi-directional relationships.
* Save a countryAdminUnitType.
*
* #param countryAdminUnitType the entity to save.
* #return the persisted entity.
*/
public CountryAdminUnitType save(CountryAdminUnitType countryAdminUnitType) {
log.debug("Request to save CountryAdminUnitType : {}", countryAdminUnitType);
CountryAdminUnitType result = countryAdminUnitTypeRepository.save(countryAdminUnitType);
countryAdminUnitTypeSearchRepository.save(result);
return result;
}
The object to be updated is set correctly when being passed to jpa repository countryAdminUnitTypeRepository.save(countryAdminUnitType);. However, the returned result object has circular dependencies and is directly forwarded to elasticsearch repository countryAdminUnitTypeSearchRepository.save(result); for update. I resolved it by only using the id of the object.
Line
CountryAdminUnitType result = countryAdminUnitTypeRepository.save(countryAdminUnitType);
countryAdminUnitTypeSearchRepository.save(result);
has been changed to
CountryAdminUnitType result = countryAdminUnitTypeRepository.save(countryAdminUnitType);
countryAdminUnitType.setId(result.getId());
countryAdminUnitTypeSearchRepository.save(countryAdminUnitType);
return result;
Thank you for the discussion. This did not work for me on entity , using Jhipster 7.8.1.
FYI, I just commented out the SearchRepository.save(result); as a quick fix to unblock development.
Issue: https://github.com/jhipster/generator-jhipster/issues/16136#issuecomment-1012404392

Performance problem when query a many-to-one relation by jpa

I use spring-boot-data-jpa-2.0 to get data from db. A table has many-to-one relation, and the query speed is too slow, 1000 lines data with foreign key will cost 15s, but by native sql it will cost only 0.07s. I search the issue and found that it is because 1+n problem.
Some solution that says use 'join fetch' in hql can solve. When I use the 'join fetch' in hql, query speed not change.
The system designed as a pure rest service, with spring boot framework.
contract entity
import java.time.LocalDateTime;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
#Entity
#Table(name = "MA_CONTRACTINFO_B")
public class MaContractinfoB implements java.io.Serializable {
// Fields
private String contractcd;
private MaDepartmentB maDepartmentB;
private Double contractid;
private String contractnm;
private String partya;
private String deputycontract;
private String prjtype;
private Double fundt;
private String bustype;
private String contractstatus;
private Double contractyear;
private String fundratio;
private LocalDateTime signdate;
private String prj;
private LocalDateTime loaddate;
private String udep;
private Double fundaccont;
private Double receipt;
private Double fundacctot;
private Double receiptot;
private String loc;
private String riskasscd;
private String rm;
private String pm;
private Double fundaccrec;
private String adminleader;
private String techleader;
private String leader;
private String progress;
private String cashadmin;
private String timetask;
private String contracttp;
// Constructors
/** default constructor */
public MaContractinfoB() {
}
/** minimal constructor */
public MaContractinfoB(String contractcd) {
this.contractcd = contractcd;
}
/** full constructor */
public MaContractinfoB(String contractcd, MaDepartmentB maDepartmentB, Double contractid, String contractnm,
String partya, String deputycontract, String prjtype, Double fundt, String bustype, String contractstatus,
Double contractyear, String fundratio, LocalDateTime signdate, String prj, LocalDateTime loaddate,
String udep, Double fundaccont, Double receipt, Double fundacctot, Double receiptot, String loc,
String riskasscd, String rm, String pm, Double fundaccrec, String adminleader, String techleader,
String leader, String progress, String cashadmin, String timetask, String contracttp) {
this.contractcd = contractcd;
this.maDepartmentB = maDepartmentB;
this.contractid = contractid;
this.contractnm = contractnm;
this.partya = partya;
this.deputycontract = deputycontract;
this.prjtype = prjtype;
this.fundt = fundt;
this.bustype = bustype;
this.contractstatus = contractstatus;
this.contractyear = contractyear;
this.fundratio = fundratio;
this.signdate = signdate;
this.prj = prj;
this.loaddate = loaddate;
this.udep = udep;
this.fundaccont = fundaccont;
this.receipt = receipt;
this.fundacctot = fundacctot;
this.receiptot = receiptot;
this.loc = loc;
this.riskasscd = riskasscd;
this.rm = rm;
this.pm = pm;
this.fundaccrec = fundaccrec;
this.adminleader = adminleader;
this.techleader = techleader;
this.leader = leader;
this.progress = progress;
this.cashadmin = cashadmin;
this.timetask = timetask;
this.contracttp = contracttp;
}
// Property accessors
#Id
#Column(name = "CONTRACTCD", unique = true, nullable = false)
public String getContractcd() {
return this.contractcd;
}
public void setContractcd(String contractcd) {
this.contractcd = contractcd;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "DEPID")
public MaDepartmentB getMaDepartmentB() {
return this.maDepartmentB;
}
public void setMaDepartmentB(MaDepartmentB maDepartmentB) {
this.maDepartmentB = maDepartmentB;
}
#Column(name = "CONTRACTID", precision = 38, scale = 8)
public Double getContractid() {
return this.contractid;
}
public void setContractid(Double contractid) {
this.contractid = contractid;
}
#Column(name = "CONTRACTNM")
public String getContractnm() {
return this.contractnm;
}
public void setContractnm(String contractnm) {
this.contractnm = contractnm;
}
#Column(name = "PARTYA")
public String getPartya() {
return this.partya;
}
public void setPartya(String partya) {
this.partya = partya;
}
#Column(name = "DEPUTYCONTRACT")
public String getDeputycontract() {
return this.deputycontract;
}
public void setDeputycontract(String deputycontract) {
this.deputycontract = deputycontract;
}
#Column(name = "PRJTYPE")
public String getPrjtype() {
return this.prjtype;
}
public void setPrjtype(String prjtype) {
this.prjtype = prjtype;
}
#Column(name = "FUNDT", precision = 38, scale = 8)
public Double getFundt() {
return this.fundt;
}
public void setFundt(Double fundt) {
this.fundt = fundt;
}
#Column(name = "BUSTYPE")
public String getBustype() {
return this.bustype;
}
public void setBustype(String bustype) {
this.bustype = bustype;
}
#Column(name = "CONTRACTSTATUS")
public String getContractstatus() {
return this.contractstatus;
}
public void setContractstatus(String contractstatus) {
this.contractstatus = contractstatus;
}
#Column(name = "CONTRACTYEAR", precision = 38, scale = 8)
public Double getContractyear() {
return this.contractyear;
}
public void setContractyear(Double contractyear) {
this.contractyear = contractyear;
}
#Column(name = "FUNDRATIO")
public String getFundratio() {
return this.fundratio;
}
public void setFundratio(String fundratio) {
this.fundratio = fundratio;
}
#Column(name = "SIGNDATE", length = 11)
public LocalDateTime getSigndate() {
return this.signdate;
}
public void setSigndate(LocalDateTime signdate) {
this.signdate = signdate;
}
#Column(name = "PRJ")
public String getPrj() {
return this.prj;
}
public void setPrj(String prj) {
this.prj = prj;
}
#Column(name = "LOADDATE", length = 11)
public LocalDateTime getLoaddate() {
return this.loaddate;
}
public void setLoaddate(LocalDateTime loaddate) {
this.loaddate = loaddate;
}
#Column(name = "UDEP")
public String getUdep() {
return this.udep;
}
public void setUdep(String udep) {
this.udep = udep;
}
#Column(name = "FUNDACCONT", precision = 38, scale = 8)
public Double getFundaccont() {
return this.fundaccont;
}
public void setFundaccont(Double fundaccont) {
this.fundaccont = fundaccont;
}
#Column(name = "RECEIPT", precision = 38, scale = 8)
public Double getReceipt() {
return this.receipt;
}
public void setReceipt(Double receipt) {
this.receipt = receipt;
}
#Column(name = "FUNDACCTOT", precision = 38, scale = 8)
public Double getFundacctot() {
return this.fundacctot;
}
public void setFundacctot(Double fundacctot) {
this.fundacctot = fundacctot;
}
#Column(name = "RECEIPTOT", precision = 38, scale = 8)
public Double getReceiptot() {
return this.receiptot;
}
public void setReceiptot(Double receiptot) {
this.receiptot = receiptot;
}
#Column(name = "LOC")
public String getLoc() {
return this.loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
#Column(name = "RISKASSCD")
public String getRiskasscd() {
return this.riskasscd;
}
public void setRiskasscd(String riskasscd) {
this.riskasscd = riskasscd;
}
#Column(name = "RM")
public String getRm() {
return this.rm;
}
public void setRm(String rm) {
this.rm = rm;
}
#Column(name = "PM")
public String getPm() {
return this.pm;
}
public void setPm(String pm) {
this.pm = pm;
}
#Column(name = "FUNDACCREC", precision = 38, scale = 8)
public Double getFundaccrec() {
return this.fundaccrec;
}
public void setFundaccrec(Double fundaccrec) {
this.fundaccrec = fundaccrec;
}
#Column(name = "ADMINLEADER")
public String getAdminleader() {
return this.adminleader;
}
public void setAdminleader(String adminleader) {
this.adminleader = adminleader;
}
#Column(name = "TECHLEADER")
public String getTechleader() {
return this.techleader;
}
public void setTechleader(String techleader) {
this.techleader = techleader;
}
#Column(name = "LEADER", length = 20)
public String getLeader() {
return this.leader;
}
public void setLeader(String leader) {
this.leader = leader;
}
#Column(name = "PROGRESS", length = 1000)
public String getProgress() {
return this.progress;
}
public void setProgress(String progress) {
this.progress = progress;
}
#Column(name = "CASHADMIN", length = 20)
public String getCashadmin() {
return this.cashadmin;
}
public void setCashadmin(String cashadmin) {
this.cashadmin = cashadmin;
}
#Column(name = "TIMETASK", length = 2000)
public String getTimetask() {
return this.timetask;
}
public void setTimetask(String timetask) {
this.timetask = timetask;
}
#Column(name = "CONTRACTTP", length = 50)
public String getContracttp() {
return this.contracttp;
}
public void setContracttp(String contracttp) {
this.contracttp = contracttp;
}
/**
* toString
*
* #return String
*/
#Override
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append(getClass().getName()).append("#").append(Integer.toHexString(hashCode())).append(" [");
buffer.append("contractcd").append("='").append(getContractcd()).append("' ");
buffer.append("maDepartmentB").append("='").append(getMaDepartmentB()).append("' ");
buffer.append("contractid").append("='").append(getContractid()).append("' ");
buffer.append("contractnm").append("='").append(getContractnm()).append("' ");
buffer.append("partya").append("='").append(getPartya()).append("' ");
buffer.append("deputycontract").append("='").append(getDeputycontract()).append("' ");
buffer.append("prjtype").append("='").append(getPrjtype()).append("' ");
buffer.append("fundt").append("='").append(getFundt()).append("' ");
buffer.append("bustype").append("='").append(getBustype()).append("' ");
buffer.append("contractstatus").append("='").append(getContractstatus()).append("' ");
buffer.append("contractyear").append("='").append(getContractyear()).append("' ");
buffer.append("fundratio").append("='").append(getFundratio()).append("' ");
buffer.append("signdate").append("='").append(getSigndate()).append("' ");
buffer.append("prj").append("='").append(getPrj()).append("' ");
buffer.append("loaddate").append("='").append(getLoaddate()).append("' ");
buffer.append("udep").append("='").append(getUdep()).append("' ");
buffer.append("fundaccont").append("='").append(getFundaccont()).append("' ");
buffer.append("receipt").append("='").append(getReceipt()).append("' ");
buffer.append("fundacctot").append("='").append(getFundacctot()).append("' ");
buffer.append("receiptot").append("='").append(getReceiptot()).append("' ");
buffer.append("loc").append("='").append(getLoc()).append("' ");
buffer.append("riskasscd").append("='").append(getRiskasscd()).append("' ");
buffer.append("rm").append("='").append(getRm()).append("' ");
buffer.append("pm").append("='").append(getPm()).append("' ");
buffer.append("fundaccrec").append("='").append(getFundaccrec()).append("' ");
buffer.append("adminleader").append("='").append(getAdminleader()).append("' ");
buffer.append("techleader").append("='").append(getTechleader()).append("' ");
buffer.append("leader").append("='").append(getLeader()).append("' ");
buffer.append("progress").append("='").append(getProgress()).append("' ");
buffer.append("cashadmin").append("='").append(getCashadmin()).append("' ");
buffer.append("timetask").append("='").append(getTimetask()).append("' ");
buffer.append("contracttp").append("='").append(getContracttp()).append("' ");
buffer.append("]");
return buffer.toString();
}
}
department entity
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
#Entity
#Table(name = "MA_DEPARTMENT_B")
public class MaDepartmentB implements java.io.Serializable {
// Fields
private Long id;
private String name;
private String leader;
private Set<MaContractinfoB> maContractinfoBs = new HashSet<MaContractinfoB>(0);
private Set<MaContraimB> maContraimBs = new HashSet<MaContraimB>(0);
// Constructors
/** default constructor */
public MaDepartmentB() {
}
/** minimal constructor */
public MaDepartmentB(Long id) {
this.id = id;
}
/** full constructor */
public MaDepartmentB(Long id, String name, String leader, Set<MaContractinfoB> maContractinfoBs,
Set<MaContraimB> maContraimBs) {
this.id = id;
this.name = name;
this.leader = leader;
this.maContractinfoBs = maContractinfoBs;
this.maContraimBs = maContraimBs;
}
// Property accessors
#Id
#Column(name = "ID", unique = true, nullable = false, precision = 10, scale = 0)
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
#Column(name = "NAME")
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
#Column(name = "LEADER")
public String getLeader() {
return this.leader;
}
public void setLeader(String leader) {
this.leader = leader;
}
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "maDepartmentB")
public Set<MaContractinfoB> getMaContractinfoBs() {
return this.maContractinfoBs;
}
public void setMaContractinfoBs(Set<MaContractinfoB> maContractinfoBs) {
this.maContractinfoBs = maContractinfoBs;
}
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "maDepartmentB")
public Set<MaContraimB> getMaContraimBs() {
return this.maContraimBs;
}
public void setMaContraimBs(Set<MaContraimB> maContraimBs) {
this.maContraimBs = maContraimBs;
}
/**
* toString
*
* #return String
*/
#Override
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append(getClass().getName()).append("#").append(Integer.toHexString(hashCode())).append(" [");
buffer.append("id").append("='").append(getId()).append("' ");
buffer.append("name").append("='").append(getName()).append("' ");
buffer.append("leader").append("='").append(getLeader()).append("' ");
buffer.append("maContractinfoBs").append("='").append(getMaContractinfoBs()).append("' ");
buffer.append("maContraimBs").append("='").append(getMaContraimBs()).append("' ");
buffer.append("]");
return buffer.toString();
}
}
jparepository
public interface MaContractinfoBRepository extends JpaRepository<MaContractinfoB, Long> {
#Query("from MaContractinfoB c join fetch c.maDepartmentB")
List<MaContractinfoB> findAll();
#Query("select contractnm from MaContractinfoB")
List<String> findAllName();
// #Query("from MaContractinfoB c join fetch c.maDepartmentB")
// List test();
}
In MaContractinfoBRepository, When I use findAllName function, it will immediately return 1000 contract names in 0.05s. When I use findAll, it will cost 15s to get 1000 data with department entity, even I add join fetch. But if I get it by native sql in db tool such as navicat, it will cost only 0.07s.
Is any keypoint I missed? How to query the MaContractinfoB table not so slowly?
This is happening because internally with 'fetch' command also hibernate is lazy loading all the rows of Department entity for each Contract id whenever you call the findAll() method. So if there are n rows in Department for 1 Contract and in total there are m Contracts then the total number of calls to the database would be 'm * n'.
One way around this is by using DTO projections. Data Transfer Objects is an easy way to define all the required columns in one query and hit the database for once.
I have found this article useful which shows multiple ways of writing DTO projections.
https://thoughts-on-java.org/dto-projections/
One of the mentioned way is: Using JPQL you can use a constructor expression to define a constructor call with the keyword new followed by the fully classified class name of your DTO and a list of constructor parameters in curly braces.
Something like this:
TypedQuery<ContractWithDepartmentDetails> q = em.createQuery(
"SELECT new com.practice.model.ContractWithDepartmentDetails(c.id, c.name, d.name) FROM contract c JOIN c.department d",
ContractWithDepartmentDetails.class);

DAO instance not working in service class - NullPointerException

In my spring boot project I created a Repository interface (which extends CRUDRepository) and an Entity class of the Table in my DB.
This is my Repo:
#Repository
public interface AuthPaymentDao extends CrudRepository<TFraudCard,String> {
#Query("SELECT t FROM TFraudCard t where t.tokenNumber = (?1)")
TFraudCard findByTokenNumber(String tokenNumber);
}
This is my Entity Class (TOKEN_NUMBER is the primary Key in the TFRAUDCARD TABLE):
#Entity
#Table(name = "TFRAUDCARD")
public class TFraudCard {
#Id
#Column(name="TOKEN_NUMBER")
private String tokenNumber;
#Column(name="TRANSACTIONNUMBER")
private int transactionNumber;
#Column(name="CARDNUMBER")
private int cardNumber;
#Column(name="DATEADDED", insertable = false, updatable = false, nullable = false)
private Timestamp dateAdded;
#Column(name="CALLINGENTITY", nullable = false)
private String callingEntity;
#Column(name="ACCOUNTID")
private String accountId;
#Column(name="ROUTINGNUMBER")
private String routingNumber;
#Column(name="BANKACCOUNTNUMBER")
private String bankAccountNumber;
#Column(name="COMMENTS")
private String comments;
#Column(name="USERID")
private String userId;
#Column(name="REMOVEDATE")
private Timestamp removeDate;
public String getTokenNumber() {
return tokenNumber;
}
public void setTokenNumber(String tokenNumber) {
this.tokenNumber = tokenNumber;
}
public int getTransactionNumber() {
return transactionNumber;
}
public void setTransactionNumber(int transactionNumber) {
this.transactionNumber = transactionNumber;
}
public int getCardNumber() {
return cardNumber;
}
public void setCardNumber(int cardNumber) {
this.cardNumber = cardNumber;
}
public Timestamp getDateAdded() {
return dateAdded;
}
public void setDateAdded(Timestamp dateAdded) {
this.dateAdded = dateAdded;
}
public String getCallingEntity() {
return callingEntity;
}
public void setCallingEntity(String callingEntity) {
this.callingEntity = callingEntity;
}
public String getAccountId() {
return accountId;
}
public void setAccountId(String accountId) {
this.accountId = accountId;
}
public String getRoutingNumber() {
return routingNumber;
}
public void setRoutingNumber(String routingNumber) {
this.routingNumber = routingNumber;
}
public String getBankAccountNumber() {
return bankAccountNumber;
}
public void setBankAccountNumber(String bankAccountNumber) {
this.bankAccountNumber = bankAccountNumber;
}
public String getComments() {
return comments;
}
public void setComments(String comments) {
this.comments = comments;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public Timestamp getRemoveDate() {
return removeDate;
}
public void setRemoveDate(Timestamp removeDate) {
this.removeDate = removeDate;
}
public TFraudCard() {
super();
}
public TFraudCard(String tokenNumber, int transactionNumber, int cardNumber, Timestamp dateAdded,
String callingEntity, String accountId, String routingNumber, String bankAccountNumber, String comments,
String userId, Timestamp removeDate) {
super();
this.tokenNumber = tokenNumber;
this.transactionNumber = transactionNumber;
this.cardNumber = cardNumber;
this.dateAdded = dateAdded;
this.callingEntity = callingEntity;
this.accountId = accountId;
this.routingNumber = routingNumber;
this.bankAccountNumber = bankAccountNumber;
this.comments = comments;
this.userId = userId;
this.removeDate = removeDate;
}
#Override
public String toString() {
return "TFraudCard [tokenNumber=" + tokenNumber + ", transactionNumber=" + transactionNumber + ", cardNumber="
+ cardNumber + ", dateAdded=" + dateAdded + ", callingEntity=" + callingEntity + ", accountId="
+ accountId + ", routingNumber=" + routingNumber + ", bankAccountNumber=" + bankAccountNumber
+ ", comments=" + comments + ", userId=" + userId + ", removeDate=" + removeDate + "]";
}
}
My Service Class:
Autowiring the DAO instance inside my Service Class:
Implementing the DAO instance inside a Method in the Service Class:
private void fraudCheck(PaymentDetail paymentDetail) throws RegularPaymentBusinessException {
logger.info("INSIDE FRAUD CHECK METHOD");
String pmtInd=paymentDetail.getPmtInd();
logger.info("pmtInd: " + pmtInd);
String tokenizedCardNum=paymentDetail.getTokenizedCardNum();
logger.info("tokenizedCardNum: " + tokenizedCardNum);
if(pmtInd.equalsIgnoreCase(VepsConstants.GIFT_CARD_IDENTIFIER) || pmtInd.equalsIgnoreCase(VepsConstants.CREDIT_CARD_IDENTIFIER) || pmtInd.equalsIgnoreCase(VepsConstants.DEBIT_CARD_IDENTIFIER)) {
logger.info("INSIDE CARD CHECK");
TFraudCard fraudCard = authPaymentDao.findByTokenNumber(tokenizedCardNum);
logger.info("fraudCard Details: " + fraudCard.toString());
if(fraudCard!=null) {
logger.info("INSIDE EXCEPTION FLOW FOR CARD FRAUD CHECK");
throw new RegularPaymentBusinessException(VepsConstants._9966, VepsConstants._9966_MESSAGE, VepsConstants.FAILURE);
}
}
}
Even though I pass the same token Number (tokenizedCardNumber) in my method as the data in the TOKEN_NUMBER column of my TFRAUDCARD table I still get a NullPointerException when I try to print a toString() of the Entity Object.
Here is the NullPointerException on my cloudFoundry logs (Click on it to see zoomed image) :
I'm providing the DB details in my dev properties file:
I have gone over every scenario in my head for why it breaks but I still can't come up with an answer. I'm using my variable marked with #Id i.e. the Primary Key for my find() method in the Repository.
I'm also adding a #Query annotation just to be even more specific.
It still does not work.

ManyToMany select query is correct and the query is viewed in console. But I cant put values into jsp

I added many to many relationship to importers and agents table..data save successfully and middle table created...but i cannot retrieve data to my jsp ...How can i retrieve agents table data to my jsp.
My model is
package lk.slsi.domain;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotEmpty;
import javax.persistence.*;
import java.util.List;
#Entity
#Table(name = "importers")
public class Importer {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "importer_id")
private long importerId;
#NotEmpty
#Column(unique = true, nullable = false)
private String importerBrc;
private String importerVatNumber;
private String importerName;
private String importerAddress1;
private String importerAddress2;
private String importerAddress3;
private String importerCityName;
private String officePhoneNumber;
private String mobilePhoneNumber;
#Email
private String email;
#Email
private String optemail1;
#Email
private String optemail2;
public String getOptemail1() {
return optemail1;
}
public void setOptemail1(String optemail1) {
this.optemail1 = optemail1;
}
public String getOptemail2() {
return optemail2;
}
public void setOptemail2(String optemail2) {
this.optemail2 = optemail2;
}
#ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JoinTable(name = "importer_agents",
joinColumns = {#JoinColumn(name = "importerId")},
inverseJoinColumns = {#JoinColumn(name = "agentId")})
private List<Agent> agentList;
public String getImporterBrc() {
return importerBrc;
}
public void setImporterBrc(String importerBrc) {
this.importerBrc = importerBrc;
}
public String getImporterVatNumber() {
return importerVatNumber;
}
public void setImporterVatNumber(String importerVatNumber) {
this.importerVatNumber = importerVatNumber;
}
public String getImporterName() {
return importerName;
}
public void setImporterName(String importerName) {
this.importerName = importerName;
}
public String getImporterAddress1() {
return importerAddress1;
}
public void setImporterAddress1(String importerAddress1) {
this.importerAddress1 = importerAddress1;
}
public String getImporterAddress2() {
return importerAddress2;
}
public void setImporterAddress2(String importerAddress2) {
this.importerAddress2 = importerAddress2;
}
public String getImporterAddress3() {
return importerAddress3;
}
public void setImporterAddress3(String importerAddress3) {
this.importerAddress3 = importerAddress3;
}
public String getImporterCityName() {
return importerCityName;
}
public void setImporterCityName(String importerCityName) {
this.importerCityName = importerCityName;
}
public String getOfficePhoneNumber() {
return officePhoneNumber;
}
public void setOfficePhoneNumber(String officePhoneNumber) {
this.officePhoneNumber = officePhoneNumber;
}
public String getMobilePhoneNumber() {
return mobilePhoneNumber;
}
public void setMobilePhoneNumber(String mobilePhoneNumber) {
this.mobilePhoneNumber = mobilePhoneNumber;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public long getImporterId() {
return importerId;
}
public void setImporterId(long importerId) {
this.importerId = importerId;
}
public List<Agent> getAgentList() {
return agentList;
}
public void setAgentList(List<Agent> agentList) {
this.agentList = agentList;
}
}
my agent table model is
package lk.slsi.domain;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotEmpty;
import javax.persistence.*;
#Entity
#Table(name = "agents")
public class Agent {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "agent_id")
private long agentId;
#NotEmpty
#Column(unique = true, nullable = false)
private String nic;
private String vatNumber;
private String name;
private String agentAddress1;
private String agentAddress2;
private String agentAddress3;
private String agentCityName;
private String officePhoneNumber;
private String mobilePhoneNumber;
#Email
private String email;
public long getAgentId() {
return agentId;
}
public void setAgentId(long agentId) {
this.agentId = agentId;
}
public String getNic() {
return nic;
}
public void setNic(String nic) {
this.nic = nic;
}
public String getVatNumber() {
return vatNumber;
}
public void setVatNumber(String vatNumber) {
this.vatNumber = vatNumber;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAgentAddress1() {
return agentAddress1;
}
public void setAgentAddress1(String agentAddress1) {
this.agentAddress1 = agentAddress1;
}
public String getAgentAddress2() {
return agentAddress2;
}
public void setAgentAddress2(String agentAddress2) {
this.agentAddress2 = agentAddress2;
}
public String getAgentAddress3() {
return agentAddress3;
}
public void setAgentAddress3(String agentAddress3) {
this.agentAddress3 = agentAddress3;
}
public String getAgentCityName() {
return agentCityName;
}
public void setAgentCityName(String agentCityName) {
this.agentCityName = agentCityName;
}
public String getOfficePhoneNumber() {
return officePhoneNumber;
}
public void setOfficePhoneNumber(String officePhoneNumber) {
this.officePhoneNumber = officePhoneNumber;
}
public String getMobilePhoneNumber() {
return mobilePhoneNumber;
}
public void setMobilePhoneNumber(String mobilePhoneNumber) {
this.mobilePhoneNumber = mobilePhoneNumber;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
my repository is
package lk.slsi.repository;
import java.util.List;
import lk.slsi.domain.Importer;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
/**
* Created by ignotus on 2/8/2017.
*/
public interface ImporterRepository extends CrudRepository<Importer,Long> {
#Override
Importer save(Importer importer);
#Override
Importer findOne(Long importerId);
#Override
List<Importer> findAll();
#Override
void delete(Long aLong);
#Override
void delete(Importer importer);
#Override
void delete(Iterable<? extends Importer> iterable);
#Query("select u from Importer u where u.importerVatNumber = :importerVatNumber")
Importer getImporterByimporterVatNumber(#Param("importerVatNumber") String importerVatNumber);
#Query("select u from Importer u inner join u.agentList where u.importerId = :importerId")
List<Importer> findAgents(#Param("importerId") long importerId);
#Query("select u from Importer u where u.importerId = :importerId")
Importer getImporterByimporterID(#Param("importerId") long importerId);
}
my services is
public List<Importer> getAllIAgents(long importerId) {
return importerRepository.findAgents(importerId);
}
My controller is
#RequestMapping(path = "/viewImporter", method = RequestMethod.POST)
public String updateImporterAll(#RequestParam("importerId") long importerId, Model model) {
slsiLogger.info("Updating user with Id [{}]", importerId);
System.out.println("Importer id is " + importerId);
model.addAttribute("importerDetails", importerServices.getImporterByimporterID(importerId));
model.addAttribute("Agentsdetail", importerServices.getAllIAgents(importerId));
return "importerEdit";
}
Jsp is
<th width="15%">Registered Agents</th>
<c:forEach items="${Agentsdetail}" var="Agent">
<tr>
<td>${Agent.agentList.vatNumber}</td>
</tr>
/c:forEach>
</thead>
The query shows in netbeans console like this
Hibernate: select importer0_.importer_id as importer1_2_, importer0_.email as email2_2_, importer0_.importer_address1 as importer3_2_, importer0_.importer_address2 as importer4_2_, importer0_.importer_address3 as importer5_2_, importer0_.importer_brc as importer6_2_, importer0_.importer_city_name as importer7_2_, importer0_.importer_name as importer8_2_, importer0_.importer_vat_number as importer9_2_, importer0_.mobile_phone_number as mobile_10_2_, importer0_.office_phone_number as office_11_2_, importer0_.optemail1 as optemai12_2_, importer0_.optemail2 as optemai13_2_ from importers importer0_ inner join importer_agents agentlist1_ on importer0_.importer_id=agentlist1_.importer_id inner join agents agent2_ on agentlist1_.agent_id=agent2_.agent_id where importer0_.importer_id=?
How can i insert agent table values to my jsp.Please help me

Spring merge - java.sql.SQLException: Invalid column index

I have a table that has 2 columns that create the primary key:
#Entity
#Table(name="DW.DW$SF$MONTHLY")
public class DWMonthly implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId DWMonthlyPK monthlyPK;
#Id
#Column(name="AID", insertable=false, updatable=false)
#IndexColumn(name="DW$SF$MONTHLY_PK")
private Long id;
#Column(name="CHNG_STATUS")
private BigDecimal chngStatus;
#Column(name="NAR")
private BigDecimal nar;
#Column(name="SF_AMID")
private String sfAmid;
#Temporal(TemporalType.TIMESTAMP)
#Column(name="N_DATE", insertable=false, updatable=false)
#IndexColumn(name="DW$SF$MONTHLY_PK")
private Date nDate;
public DWMonthly() {}
public DWMonthly(Long id, String sfAmid, Date nDate) {
this.id = id;
this.sfAmid = sfAmid;
this.nDate = nDate;
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public BigDecimal getChngStatus() {
return this.chngStatus;
}
public void setChngStatus(BigDecimal chngStatus) {
this.chngStatus = chngStatus;
}
public BigDecimal getNar() {
return this.nar;
}
public void setNar(BigDecimal nar) {
this.nar = nar;
}
public String getSfAmid() {
return this.sfAmid;
}
public void setSfAmid(String sfAmid) {
this.sfAmid = sfAmid;
}
public Date getNDate() {
return nDate;
}
public void setNarDate(Date nDate) {
this.nDate = nDate;
}
}
Embeddable table:
#Embeddable
public class DWMonthlyPK implements Serializable {
private static final long serialVersionUID = 1L;
#Column(name="AID")
private long aid;
#Temporal(TemporalType.TIMESTAMP)
#Column(name="N_DATE")
private java.util.Date nDate;
public DWMonthlyPK() {
}
public long getAid() {
return this.aid;
}
public void setAid(long aid) {
this.aid = aid;
}
public java.util.Date getNDate() {
return this.narDate;
}
public void setNDate(java.util.Date nDate) {
this.nDate = nDate;
}
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof DWMonthlyPK)) {
return false;
}
DWMonthlyPK castOther = (DWMonthlyPK)other;
return
(this.aid == castOther.aid)
&& this.nDate.equals(castOther.nDate);
}
public int hashCode() {
final int prime = 31;
int hash = 17;
hash = hash * prime + ((int) (this.aid ^ (this.aid >>> 32)));
hash = hash * prime + this.nDate.hashCode();
return hash;
}
}
Find the record and update:
#Repository(value="MonthlyNarDaoRepository")
#Import({JpaConfigurationImpl.class})
#Transactional(value="dwTransactionManager",readOnly = true, propagation=Propagation.REQUIRES_NEW)
public class MonthlyNarDaoImpl implements MonthlyNarDao {
#Override
#Transactional(value="dwTransactionManager")
public void findAndUpdateMonhtlyByAccountId(Map<DWAccount, UpsertResult> accountsLoadedResult) {
for (DWAccount dwAccount : accountsLoadedResult.keySet()){
try {
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<DWMonthlyNar> criteriaQuery = criteriaBuilder.createQuery(DWMonthlyNar.class);
Root<DWMonthlyNar> root = criteriaQuery.from(DWMonthlyNar.class);
Predicate p = criteriaBuilder.conjunction();
p = criteriaBuilder.and(criteriaBuilder.equal(root.get("id"), dwAccount.getId()), criteriaBuilder.notEqual(root.get("nar").as(BigDecimal.class), new BigDecimal(0.0)), criteriaBuilder.isNull(root.get("sfAmid")));
criteriaQuery.select(root);
criteriaQuery.where(p);
for (DWMonthlyNar dwMonthlyNar : this.entityManager.createQuery(criteriaQuery).getResultList()){
if (dwMonthlyNar.getSfAmid()==null || !dwMonthlyNar.getSfAmid().equals(accountsLoadedResult.get(dwAccount).getId())){
dwMonthlyNar.setSfAmid(accountsLoadedResult.get(dwAccount).getId());
this.entityManager.merge(dwMonthlyNar);
}
}
} catch (Exception e) {
logger.error("MonthlyNarDaoImpl.findAndUpdateMonhtlyNarByAccountId(): " + e.getMessage());
}
}
}
}
Error:
Hibernate: update DW.DW$SF$MONTHLY set CHNG_STATUS=?, NAR=?,
SF_AMID=? where AID=? and NAR_DATE=? 16:04:58.864 [main] DEBUG
o.h.e.jdbc.spi.SqlExceptionHelper - Invalid column index [n/a]
java.sql.SQLException: Invalid column index

Resources