org.hibernate.hql.internal.ast.QuerySyntaxException: table is not mapped [from table X] - hibernate-mapping

This is the Exception I get in my code:
org.hibernate.hql.internal.ast.QuerySyntaxException: product is not mapped [from Product]
This part is the problematic code.
#SuppressWarnings("unchecked")
public List<Product> getProducts() {
Session session = sessionFactory.getCurrentSession();
Query query = session.createQuery("from product");
List<Product> productList = query.list();
}
What I have been trying is the following:
1)
Query query = session.createQuery("from product");
Change => "from Product"
but it does not change Anything
2) Changing
List<Product> result = (List<User>) session.createQuery("from Product").list();
session.getTransaction().commit();
return result;
but it does not change Anything too!!
This is the full code
package kr.ac.hansung.cse.dao;
import java.util.List;
import org.hibernate.query.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import kr.ac.hansung.cse.model.Product;
#Repository
#Transactional
public class ProductDao {
#Autowired
private SessionFactory sessionFactory;
#SuppressWarnings("unchecked")
public List<Product> getProducts() {
Session session = sessionFactory.getCurrentSession();
Query query = session.createQuery("from product");
List<Product> productList = query.list();
return productList;
}
public Product getProductById(int id) {
Session session = sessionFactory.getCurrentSession();
Product product = (Product) session.get(Product.class, id);
return product;
}
public void addProduct(Product product) {
Session session = sessionFactory.getCurrentSession();
session.saveOrUpdate(product);
session.flush();
}
public void deleteProduct(Product product) {
Session session = sessionFactory.getCurrentSession();
session.delete(product);
session.flush();
}
public void updateProduct(Product product) {
Session session = sessionFactory.getCurrentSession();
session.saveOrUpdate(product);
session.flush();
}
}
HTTP Status 500 – Internal Server Error
java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: product is not mapped [from product]

Related

Value Dependent Deserialization with Jackson

I want to deserialize into a data structure. Dependent on the version of the JSON data I want to deserialize into different implementations of the same interface. And this works so far with a custom deserializer.
However, in the data structure I use references. And I expect that when undefined references are encountered an exception is thrown. The way I programmed it, this does not work together with the interface.
I created a small example with a (currently not passing) test case to show the desired behavior.
Additional Information:
In the test case, when I use concrete classes (instead of the interface) in readValue the desired behavior occurs. That is, when I write mapper.readValue(buggy, Database2.class); instead of mapper.readValue(buggy, DatabaseI.class);. But then I lose the ability to abstract from the particular content of the JSON data.
import static org.junit.jupiter.api.Assertions.assertThrows;
import com.btc.adt.pop.scen.objectstreams.Person;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.node.IntNode;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.Test;
public class Example {
#Test
public void test() throws JsonProcessingException {
ObjectMapper mapper =
new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
SimpleModule module = new SimpleModule();
module.addDeserializer(DatabaseI.class, new ToyDeserializer());
mapper.registerModule(module);
String correct = "{'version':1,'people':[{'id':'a','friends':['b','c']},{'id':'b','friends':['c']},{'id':'c','friends':['b']}]}";
DatabaseI deserCorrect = mapper.readValue(correct, DatabaseI.class);
System.out.println(mapper.writeValueAsString(deserCorrect));
String buggy = "{'version':2,'people':[{'id':'a','friends':['b','c']},{'id':'b','friends':['c']},{'id':'c','friends':['FOO']}]}";
assertThrows(Exception.class, () -> {
mapper.readValue(buggy, DatabaseI.class);
}, "The reference FOO is undefined. An Exception should be thrown.");
}
}
class Person {
#JsonProperty("id")
private String id;
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id")
#JsonIdentityReference(alwaysAsId = true)
private List<Person> friends = new ArrayList<>();
public Person() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public List<Person> getFriends() {
return friends;
}
public void setFriends(List<Person> friends) {
this.friends = friends;
}
}
interface DatabaseI {
}
class Database1 implements DatabaseI {
private int version;
private List<Person> people = new ArrayList<>();
public Database1() {
}
public List<Person> getPeople() {
return people;
}
public void setPeople(List<Person> people) {
this.people = people;
}
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
}
class Database2 implements DatabaseI {
private String version;
private List<Person> people = new ArrayList<>();
public Database2() {
}
public List<Person> getPeople() {
return people;
}
public void setPeople(List<Person> people) {
this.people = people;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
}
class ToyDeserializer extends StdDeserializer<DatabaseI> {
protected ToyDeserializer(Class<?> vc) {
super(vc);
}
public ToyDeserializer() {
this(null);
}
#Override
public DatabaseI deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JacksonException {
ObjectMapper mapper = (ObjectMapper) jp.getCodec();
JsonNode node = mapper.readTree(jp);
int version = (Integer) ((IntNode) node.get("version")).numberValue();
if (version == 1) {
return mapper.treeToValue(node, Database1.class);
} else {
return mapper.treeToValue(node, Database2.class);
}
}
}
This very good question! If you want to understand why no exception is thrown, your class Person must look like this:
#JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id",
scope = Person.class,
resolver = SimpleObjectIdResolverThrowsException.class
)
#JsonIdentityReference
class Person {
String id;
List<Person> friends = new ArrayList<>();
#ConstructorProperties({"id"})
public Person(String id) {
this.id = id;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public List<Person> getFriends() {
return friends;
}
public void setFriends(List<Person> friends) {
this.friends = friends;
}
}
class SimpleObjectIdResolverThrowsException extends SimpleObjectIdResolver {
public SimpleObjectIdResolverThrowsException() {
super();
}
#Override
public Object resolveId(ObjectIdGenerator.IdKey id) {
if (this._items == null) {
return null;
}
Object obj = this._items.get(id);
if (obj == null) {
throw new RuntimeException("Unresolved reference for: " + id);
}
return obj;
}
#Override
public ObjectIdResolver newForDeserialization(Object context) {
return new SimpleObjectIdResolverThrowsException();
}
}
Now you can set break point in the method resolveId and see what happens when we de-serialize the string "{'version':1,'people':[{'id':'a','friends':['b','c']},{'id':'b','friends':['c']},{'id':'c','friends':['b']}]}":
The problem is that the objects are processed one after the other and the references from the friends list are not resolved at that time.

How do I fix this problem it say's 'queryForObject(java.lang.String, java.lang.Object[], java.lang.Class<T>)' is deprecated

I'm not sure how to fix this since I just started doing spring boot project last Thursday. Unfortunately today is the deadline of my project so frankly I'm quite panicking right now :/
Here is my sample problem code:
#Override
public Integer getCountByEmail(String email) {
return jdbcTemplate.queryForObject(SQL_COUNT_BY_EMAIL, new Object[]{email}, Integer.class);
}
#Override
public User findById(Integer userId) {
return null;
}
Here is the overall code of the Java Class:
package com.example.Spring.boot.Repositories;
import com.example.Spring.boot.Entity.User;
import com.example.Spring.boot.Exceptions.EtAuthException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Repository;
import java.sql.PreparedStatement;
import java.sql.Statement;
#Repository
public class UserRepositoryImpl implements UserRepository {
private static final String SQL_CREATE = "INSERT INTO SB_USERS(USER_ID,
FIRST_NAME, LAST_NAME, EMAIL," +`"PASSWORD) VALUES(NEXTVAL('SB_USERS_SEQ'), ?, ?, ?, ?)";`
private static final String SQL_COUNT_BY_EMAIL = "SELECT COUNT(*) FROM SB_USERS WHERE EMAIL = ?";
private static final String ID = "SELECT USER_ID, FIRST_NAME, LAST_NAME, EMAIL, PASSWORD " +`"FROM SB_USERS WHERE USER_ID = ?";`
#Autowired
JdbcTemplate jdbcTemplate;
#Override
public Integer create(String firstName, String lastName, String email, String password) throws EtAuthException {
try {
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(connection -> {
PreparedStatement ps = connection.prepareStatement(SQL_CREATE, Statement.RETURN_GENERATED_KEYS);
ps.setString(1, firstName);
ps.setString(2, lastName);
ps.setString(3, email);
ps.setString(4, password);
return ps;
}, keyHolder);
return (Integer) keyHolder.getKeys().get("USER_ID");
}catch (Exception e) {
throw new EtAuthException("Invalid details. Failed to create account");
}
}
#Override
public User findByEmailAndPassword(String email, String password) throws EtAuthException {
return null;
}
#Override
public Integer getCountByEmail(String email) {
return jdbcTemplate.queryForObject(SQL_COUNT_BY_EMAIL, new Object[]{email}, Integer.class);
}
#Override
public User findById(Integer userId) {
return null;
}
}
The following method has been deprecated and must not be used:
public <T> T queryForObject(String sql, #Nullable Object[] args, Class<T> requiredType)
Use the following equivalent method instead:
<T> T queryForObject(String sql, Class<T> requiredType, #Nullable Object... args)
Example:
return jdbcTemplate.queryForObject(SQL_COUNT_BY_EMAIL, Integer.class, email);

#Transactional doesn't update records using HQL or SQL

I am using transactional annotation in order to enable auto-commit in Oracle DB.
When I use criteria to update records, I get the record updated successfully. But when I use HQL or SQL, in the console the query is printed but doesn't execute
This is Notification DAO
#Repository("SystemUserNotificationDao")
public class SystemUserNotificationDaoImpl extends AbstractDao<BigDecimal, SystemUserNotification> implements SystemUserNotificationDao {
#Override
public Number setNotificationsAsSeen() {
Query query = createHqlQuery("update SystemUserNotification set seen = 1 where seen = 0");
return (Number)query.executeUpdate();
}
}
This is the service
Service("SystemUserNotificationService")
#Transactional
public class SystemUserNotificationServiceImpl implements SystemUserNotificationService {
#Autowired
SystemUserNotificationDao systemUserNotificationDao;
#Override
public Number setNotificationsAsSeen() {
return systemUserNotificationDao.setNotificationsAsSeen();
}
}
This is the AbstractDao
public abstract class AbstractDao<PK extends Serializable, T> {
private final Class<T> persistentClass;
#SuppressWarnings("unchecked")
public AbstractDao() {
this.persistentClass = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[1];
}
#Autowired
private SessionFactory sessionFactory;
protected Session getSession() {
return sessionFactory.getCurrentSession();
}
#SuppressWarnings("unchecked")
public T getByKey(PK key) {
return (T) getSession().get(persistentClass, key);
}
public void persist(T entity) {
getSession().persist(entity);
}
public void update(T entity) {
getSession().update(entity);
}
public void saveOrUpdate(T entity) {
getSession().saveOrUpdate(entity);
}
public void delete(T entity) {
getSession().delete(entity);
}
protected Criteria createEntityCriteria() {
return getSession().createCriteria(persistentClass);
}
protected SQLQuery createSqlQuery(String query) {
return getSession().createSQLQuery(query);
}
protected Query createHqlQuery(String query) {
return getSession().createQuery(query);
}
}
I tried to add transaction.begin and commit but it gives me nested transactions not supported
#Override
public Number setNotificationsAsSeen() {
// Query query = createHqlQuery("update SystemUserNotification set seen = 1 where seen = 0");
Transaction tx = getSession().beginTransaction();
Query query = getSession().createQuery("update SystemUserNotification set seen = 1 where seen = 0");
Number n = (Number)query.executeUpdate();
tx.commit();
return n;
}
The issue was with SQL developer tool. there were uncommitted changes, I closed the dev tool and the update query worked fine

Creating Envers custom revision entity

I'm trying to setup audit for our project.
I started from the default configuration which works fine.
The next step is to store the user which has made changes.
Following the manual I created custom entity revision:
package com.csbi.samples.utils.audit;
import java.io.Serializable;
import java.text.DateFormat;
import java.util.Date;
import org.hibernate.envers.RevisionNumber;
import org.hibernate.envers.RevisionTimestamp;
import org.hibernate.envers.RevisionEntity;
import javax.persistence.Id;
import javax.persistence.GeneratedValue;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Transient;
#Entity
#Table(name="REVISIONS")
#RevisionEntity(CustomRevisionListener.class)
public class CustomRevisionEntity implements Serializable {
private static final long serialVersionUID = -1255842407304508513L;
#Id
#GeneratedValue
#RevisionNumber
private int id;
#RevisionTimestamp
private long timestamp;
private String username;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Transient
public Date getRevisionDate() {
return new Date(timestamp);
}
public long getTimestamp() {
return timestamp;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public boolean equals(Object o) {
if(this == o) return true;
if(!(o instanceof CustomRevisionEntity)) return false;
CustomRevisionEntity that = (CustomRevisionEntity) o;
if(id != that.id) return false;
if(timestamp != that.timestamp) return false;
if(timestamp != that.timestamp) return false;
if(username != that.username) return false;
return true;
}
public int hashCode() {
int result;
result = id;
result = 31 * result + (int) (timestamp ^ (timestamp >>> 32));
return result;
}
public String toString() {
return "DefaultRevisionEntity(user = " + username + "id = " + id + ", revisionDate = " + DateFormat.getDateTimeInstance().format(getRevisionDate()) + ")";
}
}
And also custom listener:
package com.csbi.samples.audit;
import org.hibernate.envers.RevisionListener;
public class CustomRevisionListener implements RevisionListener {
public void newRevision(Object revisionEntity) {
CustomRevisionEntity revision = (CustomRevisionEntity) revisionEntity;
revision.setUsername("username"); //for testing
}
}
Here is some lines from log:
DEBUG: org.hibernate.envers.configuration.metadata.AuditMetadataGenerator -
Generating first-pass auditing mapping for entity
com.csbi.samples.domain.Property.
DEBUG:
org.hibernate.envers.configuration.metadata.AuditMetadataGenerator -
Generating second-pass auditing mapping for entity
com.csbi.samples.domain.Property.
INFO : org.hibernate.cfg.HbmBinder
- Mapping class: com.csbi.samples.domain.Property_AUD -> PROPERTIES_AUD
INFO : org.hibernate.cfg.HbmBinder - Mapping class:
org.hibernate.envers.DefaultRevisionEntity -> REVINFO
Take a look at the last line of the output.
There is still DefaultRevisionEntity mapped instead of CustomRevisionEntity.
I have no idea what is wrong. Any suggestions?
Solved. Entity is not in scanned by Hibernate directory.

Unable to get servlet request object and session

i m trying to get session data,but i m not able to get it bcoz i m not able to get request object...
code is...
package secondary.util;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.struts2.interceptor.ServletRequestAware;
import com.opensymphony.xwork2.ActionSupport;
public class GetUserData extends ActionSupport implements ServletRequestAware
{
private static final long serialVersionUID = 1L;
private HttpServletRequest request;
private HttpSession session;
#Override
public void setServletRequest(HttpServletRequest arg0) {
this.setServletRequest(arg0);
session = request.getSession();
}
public HttpServletRequest getRequest() {
return request;
}
public void setRequest(HttpServletRequest request) {
this.request = request;
}
public GetUserData()
{
}
public String getUserLocation()
{
session = request.getSession(); // <- here
String []usr_dtl = session.getAttribute("USERDETAIL").toString().split("#");
System.out.println("User name = " + usr_dtl[6]);
return "DONE";
}
}
it gives nullpointerexception when i m getting session that portion i mark...
session = request.getSession( true );
if there is no current session and create is true, returns a new session.
UPDATE:
your request is null cause you never set the HttpServletRequest in setServletRequest().
Try
this.setRequest(arg0);
instead of
this.setServletRequest(arg0);