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
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.
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);
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
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.
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);