session.save() have some mistake with "unknown entity " - java

I'm new to hibernate and as I researched. When i want to start my JUnit, this mistake could be occur every time. I guess something wrong with my hbm.xml file. Maybe I am missing something because I'm still new to hibernate.
This is my hbm.xml file.
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.test.UserEntity" table="user" schema="" catalog="junwa">
<id name="id" column="id"/>
<property name="username" column="username"/>
<property name="gender" column="gender"/>
<property name="birthday" column="birthday"/>
<property name="addres" column="addres"/>
</class>
</hibernate-mapping>
And this is my UserEntity.java file
package com.test;
import javax.persistence.*;
import java.sql.Timestamp;
#Entity
#Table(name = "user", schema = "", catalog = "junwa")
public class UserEntity {
private int id;
private String username;
private String gender;
private Timestamp birthday;
private String addres;
#Id
#Column(name = "id")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Basic
#Column(name = "username")
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
#Basic
#Column(name = "gender")
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
#Basic
#Column(name = "birthday")
public Timestamp getBirthday() {
return birthday;
}
public void setBirthday(Timestamp birthday) {
this.birthday = birthday;
}
#Basic
#Column(name = "addres")
public String getAddres() {
return addres;
}
public void setAddres(String addres) {
this.addres = addres;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
UserEntity that = (UserEntity) o;
if (id != that.id) return false;
if (username != null ? !username.equals(that.username) : that.username != null) return false;
if (gender != null ? !gender.equals(that.gender) : that.gender != null) return false;
if (birthday != null ? !birthday.equals(that.birthday) : that.birthday != null) return false;
if (addres != null ? !addres.equals(that.addres) : that.addres != null) return false;
return true;
}
#Override
public int hashCode() {
int result = id;
result = 31 * result + (username != null ? username.hashCode() : 0);
result = 31 * result + (gender != null ? gender.hashCode() : 0);
result = 31 * result + (birthday != null ? birthday.hashCode() : 0);
result = 31 * result + (addres != null ? addres.hashCode() : 0);
return result;
}
}
This is my test file.
/**
* Created by junwa on 2017/4/2.
*/
import com.test.Students;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.Date;
public class StudentsTest {
private SessionFactory sessionFactory;
private Session session;
private Transaction transaction;
#Before
public void init(){
// create a deploy object
Configuration config = new Configuration().configure();
// create a service licenced object
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry();
// create a session factory object
sessionFactory = config.buildSessionFactory(serviceRegistry);
// create a sessoin object
session = sessionFactory.openSession();
// start transaction
transaction = session.beginTransaction();
}
#After
public void destroy(){
// commit transaction
transaction.commit();
// close session
session.close();
// close session factory
sessionFactory.close();
}
#Test
public void testSaveStudents(){
// create a object
Students s = new Students(1,"junwa","male",new Date(),"Anhui");
// save object to mysql database
session.save(s);
session.flush();
}
}
This my output
enter image description here

As Faraz Durrani said when you already have done the mapping in hbm.xml file, why do you need annotations for? Or the vice versa.You have to remove one of them. I would say remove hbm.xml file and use Annotations only.
One more thing I have noticed that you are not closing the transection also.

You can't use hbm.xml and annotation at the same time.

Related

JBoss EAP doesn't generate tables on specified database

i have an issue when attempting to generate table with JBoss EAP 7.2.
My database is named KMT on MS SQL 2014, but when i run the JBoss EAP it creates the table in the system database named "master" despite I specified KMT in my connection-URL.
I created the datasource with the admin console of the JBoss EAP and when testing the connection i got a succes message.
My connection-URL:
JNDI Name: java:/MSSQLDS
Driver Name: sqljdbc42.jar
Connection URL: jdbc:microsoft:sqlserver://localhost:1433;databasename=KMT
My persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="KMT">
<jta-data-source>java:/MSSQLDS</jta-data-source>
<properties>
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
</properties>
</persistence-unit>
</persistence>
And finally the entity I try to generate inside KMT database:
package be.Alstom.kmt.domaine;
import java.io.Serializable;
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.NotNull;
#SuppressWarnings("serial")
#Entity
#Table(name="designer", schema="kmt")
public class Designer implements Serializable{
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
#Column
#NotNull
private String userName;
#Column
#NotNull
private String password;
public Designer() {
}
public Designer(String userName, String password) {
super();
this.userName = userName;
this.password = password;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
result = prime * result + ((password == null) ? 0 : password.hashCode());
result = prime * result + ((userName == null) ? 0 : userName.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Designer other = (Designer) obj;
if (id != other.id)
return false;
if (password == null) {
if (other.password != null)
return false;
} else if (!password.equals(other.password))
return false;
if (userName == null) {
if (other.userName != null)
return false;
} else if (!userName.equals(other.userName))
return false;
return true;
}
}
Here the my MSSQL server. Hibernate create table in systemdatabase/master instead of KMT.

#Delete returns HTTP Status 405 - Method Not Allowed

Hi i am trying to delect some entities from database, but when i use #Delete i get error in browsers, but Get is working. I am using hibernate JPA
Here are my code samples
#Entity
package pl.test.model;
import javax.persistence.*;
import java.util.Collection;
#Entity
public class Mestechnologygroup {
private Integer idTechnologyGroup;
private String name;
private String description;
private Integer number;
private Collection<Mestechnology> mestechnologiesByIdTechnologyGroup;
#Id
#Column(name = "idTechnologyGroup")
public Integer getIdTechnologyGroup() {
return idTechnologyGroup;
}
public void setIdTechnologyGroup(Integer idTechnologyGroup) {
this.idTechnologyGroup = idTechnologyGroup;
}
#Basic
#Column(name = "Name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Basic
#Column(name = "Description")
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
#Basic
#Column(name = "Number")
public Integer getNumber() {
return number;
}
public void setNumber(Integer number) {
this.number = number;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Mestechnologygroup that = (Mestechnologygroup) o;
if (idTechnologyGroup != null ? !idTechnologyGroup.equals(that.idTechnologyGroup) : that.idTechnologyGroup != null)
return false;
if (name != null ? !name.equals(that.name) : that.name != null) return false;
if (description != null ? !description.equals(that.description) : that.description != null) return false;
if (number != null ? !number.equals(that.number) : that.number != null) return false;
return true;
}
#Override
public int hashCode() {
int result = idTechnologyGroup != null ? idTechnologyGroup.hashCode() : 0;
result = 31 * result + (name != null ? name.hashCode() : 0);
result = 31 * result + (description != null ? description.hashCode() : 0);
result = 31 * result + (number != null ? number.hashCode() : 0);
return result;
}
#OneToMany(mappedBy = "mestechnologygroupByIdTechnologyGroup")
public Collection<Mestechnology> getMestechnologiesByIdTechnologyGroup() {
return mestechnologiesByIdTechnologyGroup;
}
public void setMestechnologiesByIdTechnologyGroup(Collection<Mestechnology> mestechnologiesByIdTechnologyGroup) {
this.mestechnologiesByIdTechnologyGroup = mestechnologiesByIdTechnologyGroup;
}
}
presistance.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<persistence-unit name="testPU" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>pl.test.model.Mesattachmentoperation</class>
<class>pl.test.model.Mesattachmenttechnology</class>
<class>pl.test.model.Mesoperation</class>
<class>pl.test.model.Mesoperationdictionary</class>
<class>pl.test.model.Mesoperationstate</class>
<class>pl.test.model.Mesproduct</class>
<class>pl.test.model.Mesproducttype</class>
<class>pl.test.model.Mesproductxoperation</class>
<class>pl.test.model.Mesresource</class>
<class>pl.test.model.Mesresourcexoperation</class>
<class>pl.test.model.Mestechnology</class>
<class>pl.test.model.Mestechnologygroup</class>
<class>pl.test.model.Mesusers</class>
<properties>
<property name="hibernate.connection.driver_class" value="org.postgresql.Driver"/>
<property name="hibernate.connection.url" value="jdbc:postgresql://localhost:5432/mes"/>
<property name="hibernate.connection.username" value="postgres"/>
<property name="hibernate.connection.password" value="xxxx"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL9Dialect"/>
</properties>
</persistence-unit>
</persistence>
Repository with method
package pl.test.repo;
import com.sun.istack.internal.NotNull;
import pl.test.model.Mestechnologygroup;
import pl.test.model.Mesusers;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.TypedQuery;
import javax.transaction.Transactional;
import java.util.List;
import static javax.transaction.Transactional.TxType.REQUIRED;
import static javax.transaction.Transactional.TxType.SUPPORTS;
#Transactional(SUPPORTS)
public class TechnologyGroupRepo {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("testPU");
EntityManager em = entityManagerFactory.createEntityManager();
public Mestechnologygroup find(#NotNull Integer id) {
return em.find(Mestechnologygroup.class, id);
}
public List<Mestechnologygroup> findAll() {
TypedQuery<Mestechnologygroup> query = em.createQuery("from Mestechnologygroup ", Mestechnologygroup.class);
return query.getResultList();
}
#Transactional(REQUIRED)
public void delete(#NotNull Integer id) {
em.remove(em.getReference(Mestechnologygroup.class, id));
}
}
here i use #Delete
package pl.test.rest;
import pl.test.model.Mestechnologygroup;
import pl.test.repo.TechnologyGroupRepo;
import javax.inject.Inject;
import javax.validation.constraints.Min;
import javax.ws.rs.*;
import javax.ws.rs.core.Response;
import java.util.List;
import static javax.transaction.Transactional.TxType.REQUIRED;
import static javax.transaction.Transactional.TxType.SUPPORTS;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
#Path("/tg")
public class TechnologyGroupEndpoint{
#Inject
private TechnologyGroupRepo technologyGroupRepo;
#GET
#Path("/{id : \\d+}")
#Produces(APPLICATION_JSON)
public Response getBook(#PathParam("id") #Min(1) Integer id) {
Mestechnologygroup mestechnologygroup = technologyGroupRepo.find(id);
if (mestechnologygroup == null)
return Response.status(Response.Status.NOT_FOUND).build();
return Response.ok(mestechnologygroup).build();
}
#DELETE
#Path("/d/{id : \\d+}")
public Response deleteBook(#PathParam("id") #Min(1) Integer id) {
technologyGroupRepo.delete(id);
return Response.noContent().build();
}
#GET
#Produces(APPLICATION_JSON)
public Response getBooks() {
List<Mestechnologygroup> mestechnologygroups = technologyGroupRepo.findAll();
if (mestechnologygroups.size() == 0)
return Response.status(Response.Status.NO_CONTENT).build();
return Response.ok(mestechnologygroups).build();
}
}
I revice that response in Google chrome
Response
I would appreciate any help :) Thanks in advance;)
The problem that you are facing is because a browser url is always accessed via GET http method. You cannot do for other http methods.
In order to test your DELETE endpoint, you have to do it using a REST client.
A few examples of rest clients: command line: curl, wget. With GUI: Postman, Insomnia.
An example of doing this from the command line:
curl -X DELETE "http://localhost:8080/test-1.0-SNAPSHOT/resources/tg/d/22"
#Delete i get error in browsers, but Get is working.
When you hit url on browser, it takes as GET request.
you can not make any other request than GET by browser, so GET works.
Try using http client tool like postman etc. or curl.

Composite key with one to many hibernate

I'm having a big problem trying to make this little program work
Here are my objects:
Class Country
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
public class Country implements Serializable {
private static final long serialVersionUID = 4947071545454L;
private String countryID;
private String countryName;
private Set<City> cities = new HashSet<City>();
public Country() {
}
public Country(String countryID, String countryName, Set<City> cities) {
this.countryID = countryID;
this.countryName = countryName;
this.cities = cities;
}
public static long getSerialVersionUID() {
return serialVersionUID;
}
public String getCountryID() {
return countryID;
}
public void setCountryID(String countryID) {
this.countryID = countryID;
}
public String getCountryName() {
return countryName;
}
public void setCountryName(String countryName) {
this.countryName = countryName;
}
public Set<City> getCities() {
return cities;
}
public void setCities(Set<City> cities) {
this.cities = cities;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Country country = (Country) o;
return countryID != null ? countryID.equals(country.countryID) : country.countryID == null;
}
#Override
public int hashCode() {
return countryID != null ? countryID.hashCode() : 0;
}
public boolean addCity(City c){
return cities.add(c);
}
public boolean removeCity(City c){
return cities.remove(c);
}
}
Class City
import java.io.Serializable;
public class City implements Serializable{
private static final long serialVersionUID = 49470713545454L;
private String cityName;
private Country id;
public City(String cityName, Country id) {
this.cityName = cityName;
this.id = id;
}
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
public Country getId() {
return id;
}
public void setId(Country id) {
this.id = id;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
City city = (City) o;
if (cityName != null ? !cityName.equals(city.cityName) : city.cityName != null) return false;
return id != null ? id.equals(city.id) : city.id == null;
}
#Override
public int hashCode() {
int result = cityName != null ? cityName.hashCode() : 0;
result = 31 * result + (id != null ? id.hashCode() : 0);
return result;
}
}
An here are my xml archives:
country.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.samuel.hibernate.Country" table="country" catalog="training2">
<id name="country" type="string" column="countryID">
<generator class="assign"/>
</id>
<property name="countryName" type="string">
<column name="countryName" length="40" not-null="true" unique="true" />
</property>
<set name="city" inverse="true" cascade="all">
<key column="countryID" not-null="true" />
<one-to-many class="com.samuel.hibernate.City"/>
</set>
</class>
</hibernate-mapping>
city.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.samuel.hibernate.City" table="city" catalog="training2">
<composite-id name="id">
<key-many-to-one name="countryID" class="com.samuel.hibernate.Country"
column="countryID" />
<key-property name="cityName" column="cityName" type="string"/>
</composite-id>
</class>
</hibernate-mapping>
And here's my main class:
Main class
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import java.util.HashSet;
import java.util.Set;
public class Main {
public static void main(String[] args) {
System.out.println("..");
Configuration cfg=new Configuration();
cfg.configure("hibernate.cfg.xml");
// aquí es donde peta si falla conexión con Postgres
//creating seession factory object
System.out.println("Antes de crear sesion");
SessionFactory factory=cfg.buildSessionFactory();
System.out.println("Despues de crear sesion");
//creating session object
Session session=factory.openSession();
//creating transaction object
Transaction t=session.beginTransaction();
Set<City> citiesSpain = new HashSet<>();
Country spain = new Country("es","Spain",citiesSpain);
citiesSpain.add(new City("Barcelona",spain));
citiesSpain.add(new City("Madrid",spain));
session.persist(spain);
t.commit();
session.close();
factory.close();
System.out.println("END");
}
}
When I execute this code I get this error message:
Exception in thread "main" org.hibernate.HibernateException: Unable to instantiate default tuplizer [org.hibernate.tuple.component.PojoComponentTuplizer]
at org.hibernate.tuple.component.ComponentTuplizerFactory.constructTuplizer(ComponentTuplizerFactory.java:98)
at org.hibernate.tuple.component.ComponentTuplizerFactory.constructDefaultTuplizer(ComponentTuplizerFactory.java:119)
at org.hibernate.tuple.component.ComponentMetamodel.<init>(ComponentMetamodel.java:68)
at org.hibernate.mapping.Component.getType(Component.java:169)
at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:422)
at org.hibernate.mapping.RootClass.validate(RootClass.java:266)
at org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:329)
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:451)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:710)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:726)
at com.samuel.hibernate.Main.main(Main.java:22)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.hibernate.tuple.component.ComponentTuplizerFactory.constructTuplizer(ComponentTuplizerFactory.java:95)
... 10 more
Caused by: org.hibernate.PropertyNotFoundException: Could not locate getter method for property [com.samuel.hibernate.Country#cityName]
at org.hibernate.internal.util.ReflectHelper.findGetterMethod(ReflectHelper.java:418)
at org.hibernate.property.access.internal.PropertyAccessBasicImpl.<init>(PropertyAccessBasicImpl.java:41)
at org.hibernate.property.access.internal.PropertyAccessStrategyBasicImpl.buildPropertyAccess(PropertyAccessStrategyBasicImpl.java:27)
at org.hibernate.mapping.Property.getGetter(Property.java:308)
at org.hibernate.tuple.component.PojoComponentTuplizer.buildGetter(PojoComponentTuplizer.java:138)
at org.hibernate.tuple.component.AbstractComponentTuplizer.<init>(AbstractComponentTuplizer.java:47)
at org.hibernate.tuple.component.PojoComponentTuplizer.<init>(PojoComponentTuplizer.java:41)
... 15 more
I've tried looking online but I don't seem to find the solution. In my example, one country can have many cities, but one city can only have on country.
This error means that one or more setters/getters is missing. Make sure you define matching getters/setters for all your properties. And make sure that your properties annotated correctly.
I think that problem is that your cities set name is different in a class and in hbm.xml file. In your entity class you defined set as Set<City> cities and in your XML file you defined this property as name="city". So hibernate is searching setters and getters for city named property.
Make sure that variable and property name coincides. And add empty constructor in City.class.

Impossible to bypass caches with Hibernate EntityManager

Is there a problem in my code ? I cannot retrieve the changes on my User entity without restarting the application.
Here is my persistence.xml:
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="pu" transaction-type="RESOURCE_LOCAL">
<properties>
<property name = "hibernate.show_sql" value = "true" />
</properties>
</persistence-unit>
</persistence>
I create my EntityManagerFactory this way:
public static EntityManagerFactory entityManagerFactory(String driver, String url, String user, String password, DataSource datasource) {
LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
DBPoolDataSource dataSource = new DBPoolDataSource();
dataSource.setName("pool-ds");
dataSource.setDescription("Pooling DataSource");
dataSource.setDriverClassName(driver);
dataSource.setUrl(url);
dataSource.setUser(user);
dataSource.setPassword(password);
dataSource.setMinPool(5);
dataSource.setMaxPool(10);
dataSource.setMaxSize(30);
dataSource.setIdleTimeout(3600);
dataSource.setValidationQuery("SELECT id FROM test");
entityManagerFactory.setDataSource(datasource);
entityManagerFactory.setPersistenceUnitName("pu");
entityManagerFactory.setJpaDialect(new HibernateJpaDialect());
entityManagerFactory.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
Map<String, Object> props = entityManagerFactory.getJpaPropertyMap();
props.put("hibernate.cache.use_second_level_cache", "false");
props.put("hibernate.cache.use_query_cache", "false");
entityManagerFactory.afterPropertiesSet();
return entityManagerFactory.getObject();
}
Here is my Entity:
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "USER")
public class User {
#Id
private String trigram;
#Column(name = "FIRST_NAME")
private String firstName;
#Column(name = "LAST_NAME")
private String lastName;
public String getTrigram() {
return trigram;
}
public void setTrigram(String trigram) {
this.trigram = trigram;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
if (!trigram.equals(user.trigram)) return false;
if (firstName != null ? !firstName.equals(user.firstName) : user.firstName != null) return false;
return lastName != null ? lastName.equals(user.lastName) : user.lastName == null;
}
#Override
public int hashCode() {
int result = trigram.hashCode();
result = 31 * result + (firstName != null ? firstName.hashCode() : 0);
result = 31 * result + (lastName != null ? lastName.hashCode() : 0);
return result;
}
}
Here is my repository:
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.TypedQuery;
public class UserDao {
private EntityManager entityManager;
public UserDao(EntityManager entityManager) {
this.entityManager = entityManager;
}
public User getByTrigram(String trigram) throws NoResultException {
entityManager.getEntityManagerFactory().getCache().evictAll();
TypedQuery<User> q = entityManager.createQuery(
"select u from User u where u.trigram = :trigram", User.class);
q.setParameter("trigram", trigram);
q.setHint("javax.persistence.cache.retrieveMode", CacheRetrieveMode.BYPASS);
return q.getSingleResult();
}
}
-> So the entity doesn't come from L1.
entityManagerFactory.getJpaPropertyMap() contains both:
hibernate.cache.use_second_level_cache=false
hibernate.cache.use_query_cache=false
-> So there should be no L2 nor from query cache.
But still, the changes made directly in my database are retrieved by my repository only after a restart.
Someone has an idea?
Thank you!
By default, Hibernate 4 has disabled L2 cache and query cache, so it's useless to configure hibernate.cache.use_second_level_cache=false and hibernate.cache.use_query_cache=fals.
The entity is cached in the hibernate Session (L1), and if you want to refresh this particular entity according to the underlying database, you can create a method like this:
public void refresh(User user) {
org.hibernate.Session session = entityManager.unwrap(Session.class);
session.refresh(user);
}
and call it after you retrieve the user, this way:
User currentUser = userDao.getByTrigram(login);
userDao.refresh(currentUser);
Hope it helped!

ManyToOne annotation fails with Hibernate 4.1: MappingException

Using Hibernate 4.1.1.Final.
When I try to add #ManyToOne, schema creation fails with: org.hibernate.MappingException: Could not instantiate persister org.hibernate.persister.entity.SingleTableEntityPersister
User.java:
#Entity
public class User {
#Id
private int id;
public int getId() {return id;}
public void setId(int id) {this.id = id;}
#ManyToOne
Department department;
public Department getDepartment() {return department;}
public void setDepartment(Department department) {this.department = department;}
}
Department.java
#Entity
public class Department {
#Id
private int departmentNumber;
public int getDepartmentNumber() {return departmentNumber;}
public void setDepartmentNumber(int departmentNumber) {this.departmentNumber = departmentNumber;}
}
hibernate.properties:
hibernate.connection.driver_class=com.mysql.jdbc.Driver
hibernate.connection.url=jdbc:mysql://localhost:3306/dbname
hibernate.connection.username=user
hibernate.connection.password=pass
hibernate.connection.pool_size=5
hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
hibernate.hbm2ddl.auto=create
init (throwing exception):
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().buildServiceRegistry();
sessionFactory = new MetadataSources(
serviceRegistrY.addAnnotatedClass(Department.class).addAnnotatedClass(User.class).buildMetadata().buildSessionFactory();
exception throwed at init:
org.hibernate.MappingException: Could not instantiate persister org.hibernate.persister.entity.SingleTableEntityPersister
at org.hibernate.persister.internal.PersisterFactoryImpl.create(PersisterFactoryImpl.java:174)
at org.hibernate.persister.internal.PersisterFactoryImpl.createEntityPersister(PersisterFactoryImpl.java:148)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:820)
at org.hibernate.metamodel.source.internal.SessionFactoryBuilderImpl.buildSessionFactory(SessionFactoryBuilderImpl.java:65)
at org.hibernate.metamodel.source.internal.MetadataImpl.buildSessionFactory(MetadataImpl.java:340)
I have tried adding some other annotations, but shouldn't the defaults work and create the tables and foreign key? If I remove the department from User, tables get generated fine.
Thanks in advance!
You are using features not yet complete. Everything in org.hibernate.metamodel is targetting 5.0.
http://docs.jboss.org/hibernate/orm/4.1/javadocs/org/hibernate/metamodel/package-summary.html
#Entity
public class User {
#Id
private int id;
public int getId() {return id;}
public void setId(int id) {this.id = id;}
#ManyToOne
Department department;
public Department getDepartment() {return department;}
public void setDepartment(Department department) {this.department = department;}
}
#Entity
public class Department {
#Id
private int departmentNumber;
#OneToMany(mappedBy="department")
private Set<User> user;
public Set<User> getUser() {
return user;
}
public void setUser(Set<User> user) {
this.user = user;
}
public int getDepartmentNumber() {return departmentNumber;}
public void setDepartmentNumber(int departmentNumber) {this.departmentNumber = departmentNumber;}
}
You have to add a set to the Department entity and map OneToMany Relationship with the User
My example:
User.java
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
#Entity
public class User {
private int id;
private String userName;
private String password;
#Id
#GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Column
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
#Column
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
TraceLog.java
import java.util.Date;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
#Entity
public class TraceLog {
private int id;
private User user;
private String tokenId;
private String variable;
private String value;
private Date traceTime;
#Id
#GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#ManyToOne(cascade = CascadeType.ALL)
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
#Column
public String getTokenId() {
return tokenId;
}
public void setTokenId(String tokenId) {
this.tokenId = tokenId;
}
#Column
public String getVariable() {
return variable;
}
public void setVariable(String variable) {
this.variable = variable;
}
#Column
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
#Column
public Date getTraceTime() {
return traceTime;
}
public void setTraceTime(Date traceTime) {
this.traceTime = traceTime;
}
}
hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/sessiontest</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">mysql</property>
<property name="hibernate.connection.pool_size">1</property>
<property name="show_sql">true</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<mapping class="com.cpviet.example.session.model.User" />
<mapping class="com.cpviet.example.session.model.TraceLog" />
</session-factory>
</hibernate-configuration>
HibernateUtil.java
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
public class HibernateUtil {
private SessionFactory sessionFactory = null;
private static HibernateUtil instance = null;
private HibernateUtil() {
}
public static HibernateUtil getInstance() {
if (instance == null) {
instance = new HibernateUtil();
}
return instance;
}
public SessionFactory getSessionFactory() {
if (sessionFactory == null) {
Configuration configuration = new Configuration();
configuration.configure();
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
}
return sessionFactory;
}
}
How to use:
Session session = HibernateUtil.getInstance().getSessionFactory().openSession();
user = (User) session.get(User.class, (Integer)1);
session.close();
or
Session session = HibernateUtil.getInstance().getSessionFactory().openSession();
Transaction transaction = session.beginTransaction();
TraceLog traceLog = new TraceLog();
traceLog.setTokenId(tokenId);
traceLog.setVariable("var1");
traceLog.setValue("val1");
traceLog.setUser(user);
traceLog.setTraceTime(new Date());
session.save(traceLog);
transaction.commit();
session.close();

Categories