Add XML extension on project build path in Eclipse not working - java

I have added XML extension in my Java Build Path , but when I am running mvn test it is showing error
[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] F:\HibernateExample\src\main\java\net\dibyendu\hibernate\Main.java:[53,16] error: cannot find symbol
[INFO] 1 error
Also when I am trying to Run As Java Application I am not getting the my main class to execute .
Here is my Main.java file coding:
package net.dibyendu.hibernate;
import java.sql.Date;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
public class Main {
public static void main(String[] args) {
// Read
System.out.println("******* READ *******");
List employees = list();
System.out.println("Total Employees: " + employees.size());
// Write
System.out.println("******* WRITE *******");
Employee empl = new Employee("Jack", "Bauer", new Date(System.currentTimeMillis()), "911");
empl = save(empl);
}
private static List list() {
SessionFactory sf = HibernateUtil.getSessionFactory();
Session session = sf.openSession();
List employees = session.createQuery("from Employee").list();
session.close();
return employees;
}
private static Employee read(Long id) {
SessionFactory sf = HibernateUtil.getSessionFactory();
Session session = sf.openSession();
Employee employee = (Employee) session.get(Employee.class, id);
session.close();
return employee;
}
private static Employee save(Employee employee) {
SessionFactory sf = HibernateUtil.getSessionFactory();
Session session = sf.openSession();
session.beginTransaction();
Long id = (Long) session.save(employee);
employee.setId(id);
session.getTransaction().commit();
session.close();
return employee;
}
private static Employee update(Employee employee) {
SessionFactory sf = HibernateUtil.getSessionFactory();
Session session = sf.openSession();
session.beginTransaction();
session.merge(employee);
session.getTransaction().commit();
session.close();
return employee;
}
private static void delete(Employee employee) {
SessionFactory sf = HibernateUtil.getSessionFactory();
Session session = sf.openSession();
session.beginTransaction();
session.delete(employee);
session.getTransaction().commit();
session.close();
}
}
I am getting plenty of error keeping the error line in try catch :
[main] INFO org.hibernate.cfg.Environment - Hibernate 3.5.5-Final
[main] INFO org.hibernate.cfg.Environment - hibernate.properties not found
[main] INFO org.hibernate.cfg.Environment - Bytecode provider name : javassist
[main] INFO org.hibernate.cfg.Environment - using JDK 1.4 java.sql.Timestamp handling
[main] INFO org.hibernate.cfg.Configuration - configuring from resource: /hibernate.cfg.xml
[main] INFO org.hibernate.cfg.Configuration - Configuration resource: /hibernate.cfg.xml
[main] INFO org.hibernate.cfg.Configuration - Reading mappings from resource : src/main/resources/Employee.hbm.xml
Initial SessionFactory creation failed.org.hibernate.MappingNotFoundException: resource: src/main/resources/Employee.hbm.xml not found
Exception in thread "main" java.lang.ExceptionInInitializerError
at net.dibyendu.hibernate.HibernateUtil.buildSessionFactory(HibernateUtil.java:18)
at net.dibyendu.hibernate.HibernateUtil.<clinit>(HibernateUtil.java:8)
at net.dibyendu.hibernate.Main.list(Main.java:31)
at net.dibyendu.hibernate.Main.main(Main.java:17)
Caused by: org.hibernate.MappingNotFoundException: resource: src/main/resources/Employee.hbm.xml not found
at org.hibernate.cfg.Configuration.addResource(Configuration.java:665)
at org.hibernate.cfg.Configuration.parseMappingElement(Configuration.java:1679)
at org.hibernate.cfg.Configuration.parseSessionFactory(Configuration.java:1647)
at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:1626)
at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:1600)
at org.hibernate.cfg.Configuration.configure(Configuration.java:1520)
at org.hibernate.cfg.Configuration.configure(Configuration.java:1506)
at net.dibyendu.hibernate.HibernateUtil.buildSessionFactory(HibernateUtil.java:13)
... 3 more
I am very new to hibernate so please guide me.

Very nice to tell Eclipse that you've added the xml files to the classpath, but you haven't told Maven. Maven divides classpath files into 2 groups: compilable (under src/main/java and src/test/java) and non-compilable aka resources ( under src/main/resources and src/test/resources). The preferred solution is to move these xml files to the proper folder. When using m2eclipse, just update the project and eclipse will add these sourcefolders for you.
Btw. this doesn't explain the compilation error, this is just one of the issues you're facing.

Related

Fail to connect to MongoDB via HibernateOGM using sessionFactory

I am developing an application that uses Hibernate OGM to work with MongoDB. sessionFactory is used to connect, encountered an error while configuring. Log:
...
2020-12-21 11:09:06 INFO DatastoreProviderInitiator:51 - OGM000016: NoSQL Datastore provider: org.hibernate.ogm.datastore.mongodb.impl.MongoDBDatastoreProvider
2020-12-21 11:09:06 ERROR HibernateDataProvider:108 - org.hibernate.service.spi.ServiceException: OGM000072: Unable to configure datastore provider
Class HibernateUtil to get sessionFactory:
import org.hibernate.cfg.Configuration;
import org.hibernate.SessionFactory;
import org.hibernate.ogm.cfg.OgmConfiguration;
public class HibernateUtil {
private static SessionFactory sessionFactory;
public static SessionFactory getSessionFactory() {
if (sessionFactory == null) {
Configuration configuration = new OgmConfiguration();
//assuming the default mongodb settings
configuration.setProperty("hibernate.ogm.datastore.provider",
"MONGODB");
configuration.setProperty("hibernate.ogm.mongodb.host",
"127.0.0.1");
configuration.setProperty("hibernate.ogm.mongodb.port",
"27017");
configuration.setProperty("hibernate.ogm.mongodb.database",
"test");
configuration.setProperty("hibernate.ogm.datastore.create__database",
"true");
sessionFactory = configuration.buildSessionFactory();
}
return sessionFactory;
}
}
How to fix this problem?
You are missing the hibernate-ogm-mongodbdependency: https://mvnrepository.com/artifact/org.hibernate.ogm/hibernate-ogm-mongodb

Getting name from hibernate for class

I have a project with supporting XML-config. Now we wanna add hibernate config for entities via annotation. Seems it possible and works (correct me if I am mistaken). The issue is that our system
private String entityName() {
String name = null;
try {
String longName = getDaoFactory().getSessionFactory().getClassMetadata(entityClass).getEntityName();
name = longName.substring(longName.lastIndexOf(".") + 1);
} catch (Exception ex) {
log.error("Exception getting name from hibernate for class: " + entityClass);
name = null;
}
return name;
}
This method works well for entities with xml-config, but how to get a name for an entity which is configurated by annotation?
Thank you in advance for any recommendation and suggestion :)
UPD:
from init session factory method:
Configuration configuration = new Configuration();
configuration.addResource("resources/administrator/queries.hbm.xml");
StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().applySettings(configuration
.getProperties());
SessionFactory sessionFactory = configuration.buildSessionFactory(builder.build());
setSessionFactory(sessionFactory);
return configuration;
I created a session Factory like this.
public static SessionFactory buildSessionFactoryFromAnnotatedClasses(){
StandardServiceRegistry standardRegistry =
new StandardServiceRegistryBuilder().applySettings(// pass org.hibernate.cfg.Configuration object here)
.getProperties()).build(); // Configuration object has properties
MetadataSources sources = new MetadataSources(standardRegistry);
sources.addAnnotatedClass(MyClass.class);// MyClass is your java annotated class
Metadata metaData = sources.getMetadataBuilder().build();
return metaData.getSessionFactoryBuilder().build();
}

Hibernate found hibernate.cfg.xml but method no

yeah i know what you think that i didn't try resolve, check other topics etc. I read other topics but anywhere I can't find same problem as my.
Console give me this stacktrace:
20-Dec-2016 20:59:19.482 INFO [http-nio-8080-exec-7]
org.hibernate.cfg.Configuration.configure HHH000042: Configuring from file:
hibernate.cfg.xml
Enitial SessionFactory creation failedorg.hibernate.HibernateException:
could not find file: spring-mvc-angularjs-
master\src\main\java\com\user\springmvcangularjs\hibernate.cfg.xml
Well in first line i got information about that springe configuring from file hibernate.cfg.xml, but when i try connect with database i have error "could not find file".
I try all solutions but any helped me.
My code:
HibernateUtill class
public class HibernateUtil {
private static final SessionFactory ourSessionFactory;
private static final ServiceRegistry serviceRegistry;
static {
try {
Configuration configuration = new Configuration();
configuration.configure();
serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
ourSessionFactory = configuration.buildSessionFactory(serviceRegistry);
} catch (Throwable ex) {
System.err.println("Enitial SessionFactory creation failed" + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return ourSessionFactory;
}
}
Method in UserService class:
#Override
public void save(User user)
{
HibernateUtil hibernateUtil = new HibernateUtil();
SessionFactory sessFact = hibernateUtil.getSessionFactory();
Session session = sessFact.getCurrentSession();
org.hibernate.Transaction tr = session.beginTransaction();
System.out.println(tr.isActive());
session.save(user);
tr.commit();
sessFact.close();
}
PS I have hibernate.cfg.xml file in spring-mvc-angularjs-master/src/main/java

Hibernate trying to set field value to object

Trying to use Hibernate from scratch for first time.
I have entity class:
package centaurus.domain;
import javax.persistence.*;
#Entity
#Table(name="users")
public class Player {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="USER_ID")
private int id;
#Column(name="email")
private String email;
public Player(){};
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public void setId(int id) {
this.id = id;
}
public int getId() {
return id;
}
}
DAOimpl:
package centaurus.service;
import centaurus.domain.Player;
import restx.factory.Component;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.SessionFactory;
#Component
public class PlayerDAOimpl implements PlayerDAO{
private static SessionFactory factory;
public PlayerDAOimpl() {
try{
factory = new Configuration().
configure().addAnnotatedClass(Player.class).
buildSessionFactory();
//
}catch (Throwable ex) {
System.err.println("Failed to create sessionFactory object." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public Player savePlayer(Player player){
Session session = factory.openSession();
Transaction tx = null;
Integer playerID = null;
try{
tx = session.beginTransaction();
playerID = (Integer) session.save(player);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
return player;
}
public Player getPlayer(Integer playerId){
Session session = factory.openSession();
try{
Player player = (Player)session.get(Player.class, playerId);
return player;
}catch (HibernateException e) {
}finally {
session.close();
}
return null;
}
}
to demo the error i made it add a player on startupscript.
and error:
-- RESTX >> LOAD ON REQUEST << >> DEV MODE << >> AUTO COMPILE <<
-- for admin console,
-- VISIT http://127.0.0.1:9091/api/#/ui/
--
2016-05-31 21:42:48,901 [main ] [ ] INFO restx.Apps - can't enable Apidocs doclet: make sure tools.jar is in your classpath
2016-05-31 21:42:49,978 [pool-1-thread-1 ] [ ] INFO restx.classloader.CompilationManager - compilation finished: 12 sources compiled in 1.015 s
2016-05-31 21:42:50,061 [main ] [ ] INFO restx.Apps - can't enable Apidocs doclet: make sure tools.jar is in your classpath
2016-05-31 21:42:50,078 [main ] [ ] INFO restx.classloader.CompilationManager - watching for changes in [src/main/java, src/main/resources]; current location is /home/arthur/elorhia/api/.
2016-05-31 21:42:50,145 [main ] [ ] INFO org.hibernate.Version - HHH000412: Hibernate Core {5.1.0.Final}
2016-05-31 21:42:50,146 [main ] [ ] INFO org.hibernate.cfg.Environment - HHH000206: hibernate.properties not found
2016-05-31 21:42:50,147 [main ] [ ] INFO org.hibernate.cfg.Environment - HHH000021: Bytecode provider name : javassist
2016-05-31 21:42:50,802 [main ] [ ] INFO o.h.annotations.common.Version - HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
2016-05-31 21:42:50,851 [main ] [ ] WARN org.hibernate.orm.connections - HHH10001002: Using Hibernate built-in connection pool (not for production use!)
2016-05-31 21:42:50,856 [main ] [ ] INFO org.hibernate.orm.connections - HHH10001005: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost/andromeda]
2016-05-31 21:42:50,857 [main ] [ ] INFO org.hibernate.orm.connections - HHH10001001: Connection properties: {user=api, password=****}
2016-05-31 21:42:50,858 [main ] [ ] INFO org.hibernate.orm.connections - HHH10001003: Autocommit mode: false
2016-05-31 21:42:50,860 [main ] [ ] INFO o.h.e.j.c.i.DriverManagerConnectionProviderImpl - HHH000115: Hibernate connection pool size: 1 (min=1)
2016-05-31 21:42:51,090 [main ] [ ] INFO org.hibernate.dialect.Dialect - HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
2016-05-31 21:42:51,321 [main ] [ ] INFO o.h.validator.internal.util.Version - HV000001: Hibernate Validator 5.0.1.Final
START SCRIPT!
org.hibernate.property.access.spi.PropertyAccessException: Error accessing field [private java.lang.String centaurus.domain.Player.email] by reflection for persistent property [centaurus.domain.Player#email] : centaurus.domain.Player#507b79f7
at org.hibernate.property.access.spi.GetterFieldImpl.get(GetterFieldImpl.java:43)
at org.hibernate.property.access.spi.GetterFieldImpl.getForInsert(GetterFieldImpl.java:58)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.getPropertyValuesToInsert(AbstractEntityTuplizer.java:521)
at org.hibernate.tuple.entity.PojoEntityTuplizer.getPropertyValuesToInsert(PojoEntityTuplizer.java:228)
at org.hibernate.persister.entity.AbstractEntityPersister.getPropertyValuesToInsert(AbstractEntityPersister.java:4701)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:254)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:182)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:113)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:192)
at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:38)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:177)
at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:32)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73)
at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:682)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:674)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:669)
at centaurus.service.PlayerDAOimpl.savePlayer(PlayerDAOimpl.java:39)
at centaurus.Dbmaintain.start(Dbmaintain.java:26)
at restx.factory.Factory.start(Factory.java:846)
at restx.RestxMainRouterFactory.build(RestxMainRouterFactory.java:450)
at restx.RestxMainRouterFactory.newInstance(RestxMainRouterFactory.java:70)
at restx.servlet.RestxMainRouterServlet.init(RestxMainRouterServlet.java:74)
at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:519)
at org.eclipse.jetty.servlet.ServletHolder.doStart(ServletHolder.java:331)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64)
at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:747)
at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:265)
at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1250)
at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:706)
at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:492)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64)
at org.eclipse.jetty.server.handler.HandlerCollection.doStart(HandlerCollection.java:229)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64)
at org.eclipse.jetty.server.handler.HandlerCollection.doStart(HandlerCollection.java:229)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64)
at org.eclipse.jetty.server.handler.HandlerWrapper.doStart(HandlerWrapper.java:95)
at org.eclipse.jetty.server.Server.doStart(Server.java:277)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64)
at restx.server.JettyWebServer.start(JettyWebServer.java:109)
at restx.server.JettyWebServer.startAndAwait(JettyWebServer.java:114)
at centaurus.AppServer.main(AppServer.java:30)
Caused by: java.lang.IllegalArgumentException: Can not set java.lang.String field centaurus.domain.Player.email to centaurus.domain.Player
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58)
at sun.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:36)
at java.lang.reflect.Field.get(Field.java:393)
at org.hibernate.property.access.spi.GetterFieldImpl.get(GetterFieldImpl.java:39)
... 40 more
2016-05-31 21:42:51,673 [main ] [ ] INFO restx.monitor.MetricsConfiguration - registering Metrics JVM metrics
2016-05-31 21:44:41,646 [pool-2-thread-1 ] [ ] INFO restx.classloader.CompilationManager - compilation finished: 1 sources compiled in 86.94 ms
it looks like its trying to set the email field to the player object.
I cant work out why!, what have I done wrong?
EDIT: as requested i have added the code creating the player and calling the dao
package centaurus;
import centaurus.domain.Player;
import centaurus.service.PlayerDAO;
import centaurus.service.PlayerDAOimpl;
import restx.factory.AutoStartable;
import restx.factory.Component;
import javax.inject.Named;
#Component
public class Dbmaintain implements AutoStartable{
private PlayerDAO playerDAO;
public Dbmaintain(#Named("PlayerDAOimpl") PlayerDAO playerDAO) {
this.playerDAO = playerDAO;
}
public void start(){
System.out.println("START SCRIPT!");
//test
Player p = new Player();
p.setEmail("test");
playerDAO.savePlayer(p);
try {
// URL configurationUrl = new File("dbmaintain.properties").toURI().toURL();
// MainFactory mainFactory = new MainFactory(configurationUrl);
// DbMaintainer dbMaintainer = mainFactory.createDbMaintainer();
// dbMaintainer.updateDatabase(false);
} catch(Exception e) {
}
}
}
edit added git link if people wanted other bits:
https://github.com/ArthurGibbs/Centaurus-
How are you setting/creating your Player?
Caused by: java.lang.IllegalArgumentException: Can not set java.lang.String field centaurus.domain.Player.email to centaurus.domain.Player
This says, that there is an attempt to store object of class centaurus.domain.Player into a String field. For futher explanation, attach che actual code that is modifying/creating player perfore passing it to DAO
I have used your exact class Player to execute this piece of code and got no error at all. A row is inserted in table USERS correctly.
public class TestPlayer {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("TestDB");
EntityManager em = emf.createEntityManager();
Session session = (Session) em.getDelegate();
Transaction tx = session.beginTransaction();
try {
Player p = new Player();
p.setEmail("email");
session.save(p);
tx.commit();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
em.close();
emf.close();
}
}
}
The problem is not in the entity class. Maybe some changes that you made do not refresh correctly on deploy.

How to load Hibernate entities from external JAR

I am trying to load entities from several jar files.
What I managed to do is
configure hibernate
private void configure(File[] moduleFiles)
{
Configuration configuration = new Configuration()
.setProperty("hibernate.connection.url", getConnectionString())
.setProperty("hibernate.connection.username", "user")
.setProperty("hibernate.connection.password", "pass")
.setProperty("hibernate.connection.driver_class", "org.hsqldb.jdbc.JDBCDriver")
.setProperty("hibernate.dialect", "org.hibernate.dialect.HSQLDialect")
.setProperty("hibernate.archive.autodetection", "class,hbm")
.setProperty("exclude-unlisted-classes", "false")
.setProperty("hibernate.hbm2ddl.auto", "update");
if (moduleFiles != null) {
for (File f : moduleFiles) {
configuration.addJar(f);
}
}
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
this.sessionFactory = configuration.buildSessionFactory(serviceRegistry);
}
so the entities should be loaded from moduleFiles array. In logs I can see:
2015-08-25 20:52:12 INFO Configuration:837 - HHH000235: Searching for mapping documents in jar: ProgramInfo.jar
2015-08-25 20:52:12 INFO Configuration:837 - HHH000235: Searching for mapping documents in jar: SampleModule.jar
The entity in external jar
#Entity
#Table(name = "PROGRAMINFO_DATA", schema = "PUBLIC", catalog = "PUBLIC")
#NamedQueries({#NamedQuery(name = "PrograminfoDataEntity.findByWindowInfo", query = "FROM PrograminfoDataEntity WHERE PROCESSPATH = :pp AND WINDOWTITLE = :wt AND DAY = :d")})
public class PrograminfoDataEntity implements SVEntity {
private long id;
private Date day;
private String processname;
private String processpath;
private String programname;
private String windowtitle;
// getters setters etc.
}
persistence.xml in external jar (META-INF directory)
<persistence-unit name="ProgramInfoPersistenceUnit">
<class>com.antara.modules.programinfo.db.model.PrograminfoDataEntity</class>
</persistence-unit>
Query with above entity usage
Session session = openSession();
Query q = session.getNamedQuery("PrograminfoDataEntity.findByWindowInfo");
q.setParameter("pp", windowInfo.getProcessPath());
q.setParameter("wt", windowInfo.getWindowTitle());
q.setDate("d", date);
PrograminfoDataEntity result = (PrograminfoDataEntity) q.uniqueResult();
closeSession(session);
which threw an exception:
org.hibernate.MappingException: Named query not known: PrograminfoDataEntity.findByWindowInfo
at org.hibernate.internal.AbstractSessionImpl.getNamedQuery(AbstractSessionImpl.java:177)
at org.hibernate.internal.SessionImpl.getNamedQuery(SessionImpl.java:1372)
at com.antara.modules.programinfo.db.dao.PrograminfoDao.findByWindowInfo(PrograminfoDao.java:26)
at com.antara.modules.programinfo.ProgramInfoImpl.run(ProgramInfoImpl.java:84)
The question is why hibernate didn't loaded the annotated entity from jar? The exception is thrown not only by named query, but any other operation with entity. There are no errors before usage of this entity. Local entities are loaded properly.
EDIT:
After some changes I managed to recognize entity by Hibernate
DEBUG AnnotationBinder:601 - Binding entity from annotated class: com.antara.modules.programinfo.db.model.PrograminfoDataEntity
DEBUG QueryBinder:93 - Binding named query: PrograminfoDataEntity.findByWindowInfo => FROM PrograminfoDataEntity ....
But when I try to use the entity I still get exception:
ERROR AssertionFailure:61 - HHH000099: an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session): java.lang.ClassNotFoundException: com.antara.modules.programinfo.db.model.PrograminfoDataEntity
ERROR Main:114 - PersistentClass name cannot be converted into a Class
...
Caused by: java.lang.ClassNotFoundException: com.antara.modules.programinfo.db.model.PrograminfoDataEntity
The change was: passing Configuration to each "module" that is inside jar and add Annotated Class (by module I mean SPI service with method invoked at startup)
#Override
public void configureDB(Configuration configuration) {
configuration.addAnnotatedClass(PrograminfoDataEntity.class);
}
After 3 days of trials I have found the solution: Hibernate loades classes using reflection mechanism by ContextClassLoader
Thread.currentThread().getContextClassLoader();
so I set ContextClassLoader to ClassLoader of PrograminfoDataEntity
Thread.currentThread().setContextClassLoader(PrograminfoDataEntity.class.getClassLoader());
and it solved all NoClassDefFound, ClassCastException and similar errors
According to javadoc and implementation code Hibernate only read *.hbm.xml at Configuration.addJar method
I guess Hibernate doesn't auto scan jars because of restrictions in JPA Specification
I've done auto scan of jars in hibernate extending the scanner and adding the jars on it. But you should use JPA api to that. Something like:
Map<String, Object> map = new HashMap<>();
map.put("hibernate.connection.url", getConnectionString());
map.put("hibernate.connection.username", "user");
map.put("hibernate.connection.password", "pass");
map.put("hibernate.connection.driver_class", "org.hsqldb.jdbc.JDBCDriver");
map.put("hibernate.dialect", "org.hibernate.dialect.HSQLDialect");
map.put("hibernate.archive.autodetection", "class,hbm");
map.put("exclude-unlisted-classes", "false");
map.put("hibernate.hbm2ddl.auto", "update");
//Property to change scanner
map.put("hibernate.ejb.resource_scanner", "me.janario.MyScanner");
EntityManagerFactory emf = Persistence.createEntityManagerFactory("ProgramInfoPersistenceUnit", map);
SessionFactory sessionFactory = ((HibernateEntityManagerFactory) emf).getSessionFactory();
And the scanner something like:
public class MyScanner extends StandardScanner {
#Override
public ScanResult scan(PersistenceUnitDescriptor persistenceUnit, ScanOptions scanOptions) {
try {
persistenceUnit.getJarFileUrls()
.add(new URL("file:/path/my.jar"));
return super.scan(persistenceUnit, scanOptions);
} catch (MalformedURLException e) {
throw new IllegalStateException(e);
}
}
}
You are setting up a Hibernate bootstrap process. Here are the docs: https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#bootstrap
There are essentially two routes to go down here. You are doing it the Hibernate-specific way. I prefer the JPA one usually because it's the most automatic and simplistic one: you put a persistence.xml file into a jar and that jar will get scanned for classes with the appropriate Entity annotation. JPA will then inject the entity manager (and factory), which you can then in turn transform into the native Hibernate session using:
Session s = (Session) em.getDelegate();
That in turn, should give you access to non-JPA capabilities if need be.

Categories

Resources