SpringMVC+Hibernate : criteria.list() is returning an empty list - spring

I am using spring MVC with Hibernate, The aim is to get the table data and store it in a list.Here the entity class being used :
package com.bng.core.entity;
// default package
// Generated Oct 25, 2015 4:38:03 PM by Hibernate Tools 3.4.0.CR1
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* servicenames generated by hbm2java
*/
#Entity
#Table(name = "servicenames")
public class ServiceNames implements java.io.Serializable {
private Integer id;
private String serviceName;
public ServiceNames() {
}
public ServiceNames(String servicename) {
this.serviceName = servicename;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id", unique = true, nullable = false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
#Column(name = "servicename", length = 25)
public String getServiceName() {
return this.serviceName;
}
public void setServiceName(String servicename) {
this.serviceName = servicename;
}
}
And the method used to get the list :
#Transactional
#Override
public List<ServiceNames> getServiceNames() {
Logger.sysLog(LogValues.APP_INFO, this.getClass().getName(), "Getting all Service names.");
Session session = sessionFactoryGlobal.openSession();
Criteria criteria = session.createCriteria(ServiceNames.class);
List<ServiceNames> serviceNamesList = criteria.list();
session.close();
return serviceNamesList;
}
When the method is called it returns an empty list. Please suggest where its going wrong ?

I think you are sure your table servicenames has data. So such problem can be when #Transactional is not working properly. Try to get list without #Transactional by open and close a transaction manually.

Related

Why am I getting null for the date when I create a Todo entity?

What is wrong with my to-do application? I want the user to be able to add a todo and have it be saved in my MySQL database with the time it was created, but I don't know what I'm doing wrong.
I am new to learning Springboot and would appreciate any suggestions or advice.
Todo Entity:
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.CreationTimestamp;
import javax.persistence.*;
import java.util.Date;
#Entity(name = "Todo")
#NoArgsConstructor
#Table(name = "todos")
public class Todo {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int id;
#Column(name="description")
private String description;
#Column(name="target_date")
#CreationTimestamp
private Date targetDate;
public Todo(String description) {
this.description = description;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Date getTargetDate() {
return targetDate;
}
public void setTargetDate(Date targetDate) {
this.targetDate = targetDate;
}
#Override
public String toString() {
return "Todo{" +
"id=" + id +
", description='" + description + '\'' +
", targetDate=" + targetDate +
'}';
}
}
Adding a Todo with Spring Data JPA
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import javax.transaction.Transactional;
import java.util.List;
#Repository
#Component
public interface TodoRepository extends JpaRepository<Todo, Integer> {
#Modifying
#Query(value = "INSERT INTO todos (description) VALUES (:description)", nativeQuery=true)
#Transactional
void addTodo(#Param("description") String description);
}
TodoController
#RestController
#RequestMapping(value = "/api/v1/todos")
#AllArgsConstructor
public class TodoController {
#Autowired
private ITodoService todoService;
#PostMapping(value = "/add-todo")
public String addTodo(#RequestParam String description) {
Todo todo = new Todo();
todo.setDescription(description);
todoService.addTodo(todo);
return todo.toString();
}
after getting a post request, the target_date is getting NULL in MySQL
I assume you can solve it by using persist():
#Autowired EntityManager entityManager;
#PostMapping(value = "/add-todo")
public String addTodo(#RequestParam String description) {
Todo todo = new Todo();
todo.setDescription(description);
entityManager.persist(todo);
return todo.toString();
}

Get from VIEW in Spring boot

I am beginner with Spring Boot and trying to improve my skills to get new job, so I hope you help me even if the question maybe easy for you as I search a lot and gain nothing.
I need to get by id, but return data is duplicated with only one record, I will show you what I do and the result for more explanation.
In DB side:
I have VW_Prices view in DB and it's data as shown below:
In Spring Boot side:
VW_Prices class is :
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.Immutable;
#Entity
#Table(name = "VW_PRICES")
public class VW_Prices implements Serializable {
private long dealId;
private Long quotationId;
private Long productPriceForEjada;
private Long productPriceForClient;
private Long productId;
private Long productQuantity;
private String productName;
#Id
#Column(name = "ID")
public long getDealId() {
return dealId;
}
public void setDealId(long dealId) {
this.dealId = dealId;
}
#Column(name = "PRODUCT_QUANTITY")
public Long getProductQuantity() {
return productQuantity;
}
public void setProductQuantity(Long productQuantity) {
this.productQuantity = productQuantity;
}
#Column(name = "PRODUCT_NAME")
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
#Column(name = "PRODUCT_PRICE_FOR_EJADA")
public Long getProductPriceForEjada() {
return productPriceForEjada;
}
public void setProductPriceForEjada(Long productPriceForEjada) {
this.productPriceForEjada = productPriceForEjada;
}
#Column(name = "PRODUCT_PRICE_FOR_CLIENT")
public Long getProductPriceForClient() {
return productPriceForClient;
}
public void setProductPriceForClient(Long productPriceForClient) {
this.productPriceForClient = productPriceForClient;
}
#Column(name = "PRODUCT_ID")
public Long getProductId() {
return productId;
}
public void setProductId(Long productId) {
this.productId = productId;
}
#Column(name = "QUOTATION_ID")
public Long getQuotationId() {
return quotationId;
}
public void setQuotationId(Long quotationId) {
this.quotationId = quotationId;
}
}
and I create VW_PricesRepository
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import springboot.deals_tracker_system.models.VW_Prices;
import springboot.deals_tracker_system.models.VW_Prices_interface;
public interface VW_PricesRepository extends JpaRepository<VW_Prices, Long> {
#Query( nativeQuery = true,value = "SELECT distinct * from VW_Prices v where v.id = :dealID " )
List<VW_Prices> findByDealId( #Param("dealID") Long id);
}
and my in my Service
public List<VW_Prices> findByDealId(Long dealId) {
System.out.println("we are in service");
List<VW_Prices> variableForDebug = VW_pricesRepository.findByDealId(dealId);
for (VW_Prices vw_Prices : variableForDebug) {
System.out.println(vw_Prices.getDealId() + " " + vw_Prices.getProductName());
}
return variableForDebug;
//return VW_pricesRepository.findByDealId(dealId);
}
When I pass dealId = 39 the result comes duplicated and not correct as in below:
how can I get correct data??
The view is made for Quotation Product Table to get product name.
i think the problem is the id annotation you must add GeneratedValue
fro the class:
#Entity
#Table(name = "VW_PRICES")
public class VW_Prices implements Serializable {
#Id
#GeneratedValue (strategy = GenerationType.IDENTITY)
private long dealId;
private Long quotationId;
private Long productPriceForEjada;
private Long productPriceForClient;
private Long productId;
private Long productQuantity;
private String productName;
//code..
}
You dont have to use JPQL for this type of queries it's already exist in jpa:
VW_PricesRepository:
public interface VW_PricesRepository extends JpaRepository<VW_Prices, Long> {
}
to get data by id use findById like that:
public VW_Prices findByDealId(Long dealId) {
System.out.println("we are in service");
VW_Prices vw_Prices = VW_pricesRepository.findById(dealId);
System.out.println(vw_Prices.getDealId() + " " +
vw_Prices.getProductName());
}
return vw_Prices;
}
All data should be deleted from VW_Prices table because ids are not unique, try to insert new data with unique id then try the above code
I detect the problem, The view has main table Quotation and I didn't select it's ID and I used ID of the secondary table as the main ID for the View
I just write it if any one Google for such problem

I18n for custom error messages into JPA entity

I looking to understand how to internationalize JPA entity error message. I understand how its work into a controller using autowired MessageSource but in my case I want to do this into a JPA entity. I'm not intresting about using the same way as the controller issue because I think is not optimized to autowired the full MessageSource on this entity. If someone have a simple example to show me how its work with a simple entity like mine. My project using spring-boot 2.2 ; JPA ; and thymeleaf.
The entity I using:
package com.bananasplit.weblab2.entities;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
#Entity
#Table(name = "todo")
public class Todo {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name = "id")
private Long id;
#Column(name = "name", nullable = false)
#NotEmpty
#Size(min=2, max=30) // error message is already internationalized here with spring-boot
private String name;
#Column(name = "category", nullable = false)
#NotEmpty
#Pattern(regexp="(WORK|PERSONAL|SPECIAL)",
message="Category must be WORK or PERSONNAL or SPECIAL.") // here is the message I want to internationalize
private String category;
public Todo() {}
public Todo(String name, String category) {
this.name = name;
this.category = category;
}
#Override
public String toString() {
return String.format(
"Todo[id=%d, name='%s', category='%s']",
id, name, category);
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
}
By default Spring boot uses this ValidationMessages.properties but you can override by adding this file in resources.
#Size(min=2, max=30, message="{empty.todo.name")
private String name;
In ValidationMessages.properties file
empty.todo.name = Cannot be blank
If you want to manage which package messages should be scanned by Spring then should follow this link

Hibernate Envers unable to extend DefaultRevisionEntity

I'm trying to extend the DefaultRevisionEntity in order to add a username to the current revision entity. However, instead of simply adding the new field, it's creating a completely new table. Code is as follows
AuditRevisionEntity
package com.example.demo;
import org.hibernate.envers.DefaultRevisionEntity;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
#Entity
#EntityListeners(AuditRevisionListener.class)
public class AuditRevisionEntity extends DefaultRevisionEntity {
private String user;
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
}
AuditRevisionListener
package com.example.demo;
import org.hibernate.envers.RevisionListener;
public class AuditRevisionListener implements RevisionListener {
#Override
public void newRevision(Object revisionEntity) {
AuditRevisionEntity rev = (AuditRevisionEntity) revisionEntity;
rev.setUser("MYUSER");
}
}
User
package com.example.demo;
import org.hibernate.envers.Audited;
import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
#Entity
#Audited
#Table(name = "users")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#NotBlank()
#Size(min = 1, max = 100)
#Column(name = "email")
private String email;
#NotBlank()
#Size(min = 1, max = 100)
#Column(name = "password")
private String password;
}
Resulting in
Your custom RevisionEntity is missing the required #RevisionEntity annotation.
package com.example.demo;
import org.hibernate.envers.DefaultRevisionEntity;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
#Entity
#RevisionEntity( AuditRevisionListener.class )
public class AuditRevisionEntity extends DefaultRevisionEntity {
private String user;
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
}
More info and a code sample can be found in the Envers documentation
I believe I have fixed this with adding the table to the custom entity pointing to the main revinfo table
#Entity
#RevisionEntity( AuditRevisionListener.class )
#Table(name = "revinfo")
public class AuditRevisionEntity extends DefaultRevisionEntity {
private String user;
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
}

hibernate & spring, invalid identifier

I have stuck on dealing with DB by using hibernate orm in spring mvc environment.
I have some tables; but I'm not gonna tell you my tables(If you want, I will edit this post)
The problem is that when hibernate runs, it generates sql - I can see the sql by configuring "hbm2_ddl auto" - but the sql has invalid identifier.
select newsreplie0_.news_article# as news6_3_4_, newsreplie0_.reply# as reply1_4_,
newsreplie0_.reply# as reply1_4_3_, newsreplie0_.account_account# as account5_4_3_,
newsreplie0_.content as content4_3_, newsreplie0_.dt as dt4_3_,
newsreplie0_.news_article# as news6_4_3_, newsreplie0_.reply_at as reply4_4_3_,
account1_.account# as account1_0_0_, account1_.email as email0_0_,
account1_.passwd as passwd0_0_, accountpro2_.account# as account1_1_1_,
accountpro2_.nickname as nickname1_1_, accountsec3_.account# as account1_2_2_,
accountsec3_.activate_key as activate2_2_2_, accountsec3_.activated as activated2_2_,
accountsec3_.enabled as enabled2_2_, accountsec3_.login_failed as login5_2_2_
from news_reply newsreplie0_
left outer join
cookingstep.account account1_ on newsreplie0_.account_account#=account1_.account#
left outer join
cookingstep.account_profile accountpro2_ on account1_.account#=accountpro2_.account#
left outer join
cookingstep.account_security accountsec3_ on account1_.account#=accountsec3_.account#
where newsreplie0_.news_article#=9
{FAILED after 4 msec}
The above statement is a sql generated by hibernate. And the error is:
java.sql.SQLSyntaxErrorException:
ORA-00904: "NEWSREPLIE0_"."ACCOUNT_ACCOUNT#": Invalid Identifier
In that exception message, there is a column called "ACCOUNT_ACCOUNT#".
It should be just "ACCOUNT#", not following "ACCOUNT_".
So, how to remove the word ?
EDIT:
Thank you all for your reply. I have asked similar question before.
And I checked out that article, it seems the problem was #JoinColumn annotation missing. Now it works out.
Here is my Entities.
Account.java for user information
package com.musicovery12.cookingstep.persistence.model;
import java.io.Serializable;
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.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
#Entity
#Table(name="account", catalog="cookingstep", uniqueConstraints= {
#UniqueConstraint(columnNames="email")
})
public class Account implements Serializable{
private static final long serialVersionUID = 1L;
private int accountId;
private String email;
private String password;
private Set<UserRole> userRoles = new HashSet<UserRole>(0);
private AccountProfile profile;
private AccountSecurity security;
private Set<News> newsList;
private Set<NewsReply> newsReplyList;
public Account() {}
#Id
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator="seq_account")
#SequenceGenerator(name="seq_account", sequenceName="seq_account", allocationSize=1)
#Column(name="account#", unique=true, nullable=false)
public int getAccountId() {
return accountId;
}
public void setAccountId(int accountId) {
this.accountId = accountId;
}
#Column(name="email", unique=true, nullable=false)
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
#Column(name="passwd", nullable=false)
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#OneToMany(mappedBy="pk.account", fetch=FetchType.EAGER, cascade=CascadeType.ALL)
public Set<UserRole> getUserRoles() {
return userRoles;
}
public void setUserRoles(Set<UserRole> userRoles) {
this.userRoles = userRoles;
}
#OneToOne(mappedBy="account", fetch=FetchType.EAGER, cascade=CascadeType.ALL)
public AccountProfile getProfile() {
return profile;
}
public void setProfile(AccountProfile profile) {
this.profile = profile;
}
#OneToOne(mappedBy="account", fetch=FetchType.EAGER, cascade=CascadeType.ALL)
public AccountSecurity getSecurity() {
return security;
}
public void setSecurity(AccountSecurity security) {
this.security = security;
}
#OneToMany(mappedBy="account", fetch=FetchType.LAZY, cascade=CascadeType.ALL)
public Set<News> getNewsList() {
return newsList;
}
public void setNewsList(Set<News> newsList) {
this.newsList = newsList;
}
#OneToMany(mappedBy="account", fetch=FetchType.LAZY, cascade=CascadeType.ALL)
public Set<NewsReply> getNewsReplyList() {
return newsReplyList;
}
public void setNewsReplyList(Set<NewsReply> newsReplyList) {
this.newsReplyList = newsReplyList;
}
}
and NewsReply.java for news community article's reply list.
package com.musicovery12.cookingstep.persistence.model;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
#Entity
#Table(name="news_reply")
public class NewsReply {
private int replyId;
private News news;
private Date date;
private String content;
private Account account;
private int replyAt;
#Id
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator="gen_seq")
#SequenceGenerator(name="gen_seq", sequenceName="gen_seq", allocationSize=1)
#Column(name="reply#", unique=true, nullable=false)
public int getReplyId() {
return replyId;
}
public void setReplyId(int replyId) {
this.replyId = replyId;
}
#Temporal(TemporalType.DATE)
#Column(name="dt")
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
#Column(name="content", nullable=false)
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
#Column(name="reply_at")
public int getReplyAt() {
return replyAt;
}
public void setReplyAt(int replyAt) {
this.replyAt = replyAt;
}
#ManyToOne
public News getNews() {
return news;
}
public void setNews(News news) {
this.news = news;
}
#ManyToOne
#JoinColumn(name="account#", referencedColumnName="account#")
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
}
in NewsReply.java, there was no JoinColumn annotation to point foreing key column name.
Thank you.
#ManyToOne
#JoinColumn(name="account#", referencedColumnName="account#")
public Account getAccount() {
return account;
}
This is the problem, you tell hibernate the table has a technical name of account# what is not allowed.
What you can do is to force hibernate to use that # by defining
#ManyToOne
#JoinColumn(name="`account#`", referencedColumnName="`account#`")
public Account getAccount() {
return account;
}
But this is bad style and you have to do it on the owning-side too.
Why dont you let hibernate create the entitys for you? He is much more precisly!

Resources