I am trying to fetch data from table I am using following code to fetch data from db.
public List<UserInfoSetting> fetchAll(Long aid) {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
Transaction tx = session.beginTransaction();
List<UserInfoSetting> obj = null;
try {
String hql = "select s from UserInfoSetting s where s.atom.id=:aid ";
Query query = session.createQuery(hql);
query.setParameter("aid", aid);
obj = query.list();
tx.commit();
} catch (HibernateException e) {
if (tx != null) {
tx.rollback();
}
} finally {
session.close();
}
return obj;
}
HibernateUtil.java
public class HibernateUtil {
private static final SessionFactory sessionFactory;
static {
try {
sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
It is showing following exception
root cause
java.lang.NoClassDefFoundError: Could not initialize class business.HibernateUtil
setting.user.UserCommunicationDao.fetchAll(UserCommunicationDao.java:146)
setting.user.UserCommunication.fetchAll(UserCommunication.java:64)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:483)
How to resolve the above problem
This means either you haven't got all the right Hibernate libraries in your class path, or you're not including the classes you've written. If you're coding using Eclipse, find the project settings and add the Hibernate libraries as dependencies for the project.
You will need to add hibernate-core, but quite a few others too.
Maven would help...
And it would help you a lot if you changed the name of your HibernateUtil class: there is a standard Hibernate class with the same name. Although in principle you can have two classes with the same name but in different packages, it'll be likely to cause confusion. (For instance, it's not entirely clear which one it can't find.)
Related
I am unable to catch ConstraintViolationException
public BigDecimal createSubBoard(SubBoard subBoardObj, Users user) {
EntityManager em = EMFUtility.getEntityManager();
EntityTransaction et = null;
SubBoards subBoard = null;
SubBoard subBoards = null;
Boards board = null;
BigDecimal subBoardId = new BigDecimal(0);
try {
logger.debug(" #### BoardsDao - createSubBoard"+subBoardObj.toString());
et = em.getTransaction();
et.begin();
try{
subBoardObj.setCreateDate(new Date());
subBoardObj.setCreatedBy(user.getEdipi());
em.persist(subBoardObj);
subBoardId = subBoardObj.getId();
et.commit();
} catch(EJBTransactionRolledbackException ce) {
System.out.println("!!!");
Throwable t = ce.getCause();
while ((t != null) && !(t instanceof ConstraintViolationException)) {
t = t.getCause();
}
if (t instanceof ConstraintViolationException) {
System.out.println("...........");
// Check here if the delete date is also null
}
}
///TODO..///
} catch (Exception e) {
et.rollback();
e.printStackTrace();
System.out.println("!!!! "+e.getCause() );
logger.debug(" #### BoardsDao - createSubBoard :Exception is " + e.getMessage());
throw new PersistenceException("Error persisting entity in createSubBoard "+ e.getMessage());
} finally {
em.close();
}
return subBoardId;
}
in this code em.persist(subBoardObj); throws ConstraintViolationException. I tried using getCause() and identify if constraintViolation but the code control doesnt goto that catch block. It goes to generic Exception block. Can someone suggest whats wrong.
First of all, I would not recommend doing transaction handling manually but instead use declarative transaction management. If you use EJBs, you just need to annotate the bean as #Stateless or if you want to change the transaction demacration strategy use the #TransactionAttribute annotation on the method. If you really must use manual transaction management you should use the UserTransaction interface. This is because EJB works with the JTA specification which you probably also configured as transaction strategy in your persistence unit.
Having said that, EntityManager.persist and EntityManager.flush throw javax.persistence.PersistenceException that wrap a org.hibernate.exception.ConstraintViolationException. So you need to catch the PersistenceException and then use getCause to get the constraint violation.
There's an example from the web on how to use annotations in Hibernate (before that I've worked on the same example, but it used .xml instead. And I've managed to make it work without exceptions).
So now I have:
Initial session factory creation failedjava.lang.NoSuchFieldError: namingStrategy
Exception in thread "main" java.lang.ExceptionInInitializerError
at firstproject.HibernateUtil.<clinit>(HibernateUtil.java:14)
at firstproject.StudentDAO.addSubject(StudentDAO.java:82)
at firstproject.Test.main(Test.java:12) Caused by: java.lang.NoSuchFieldError: namingStrategy
at org.hibernate.cfg.AnnotationConfiguration.reset(AnnotationConfiguration.java:250)
at org.hibernate.cfg.Configuration.<init>(Configuration.java:125)
at org.hibernate.cfg.Configuration.<init>(Configuration.java:119)
at org.hibernate.cfg.AnnotationConfiguration.<init>(AnnotationConfiguration.java:108)
at firstproject.HibernateUtil.<clinit>(HibernateUtil.java:11)
... 2 more
Here is some code, that may help:
public class HibernateUtil {
private static final SessionFactory sessionFactory;
static {
try {
sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory(); // HibernateUtil.java:11
} catch (Throwable ex) {
System.err.println("Initial session factory creation failed" + ex);
throw new ExceptionInInitializerError(ex); // HibernateUtil.java:14
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
public class StudentDAO {
public Long addSubject(Subject subject) {
Session session = HibernateUtil.getSessionFactory().getCurrentSession(); // StudentDAO.java:82
session.beginTransaction();
Long result = (Long) session.save(subject);
session.getTransaction().commit();
return result;
}
}
public class Test {
public static void main(String[] args) {
StudentDAO dao = new StudentDAO();
Subject subject = new Subject();
subject.setSubjectName("Mathematics");
dao.addSubject(subject); // Test.java:12
}
}
Hi Kleeo
You have written the following line in HibernateUtil class.
sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
Replace this line of code with the below written line & retry. I hope this will work for you.
sessionFactory = new Configuration().configure().buildSessionFactory();
AnnotationConfiguration has been Deprecated in Hibernate 3.6.
As you can see in the documentation (see link below) all functionality has been moved to Configuration.
You can use safely Configuration instead.
sessionFactory = new Configuration().configure().buildSessionFactory();
AnnotationConfiguration documentation:
http://docs.jboss.org/hibernate/core/3.6/javadocs/org/hibernate/cfg/AnnotationConfiguration.html
Use below :
sessionFactory = new Configuration().configure().buildSessionFactory();
And also ensure that your cfg.xml should be present in root of src folder. Else you will get exception of unable to find cfg file
Can someone please tell me why am I geting java.sql.SQLException: This function is not supported using HSQL and Spring? I am trying to insert a new row into my database..
Below is my DAO and I get the error on the mySession.save(message) line:
#Transactional
#Repository
public class MessageDaoImpl implements MessageDao
{
private Log log = null;
#Autowired
private SessionFactory sessionFactory;
public MessageDaoImpl()
{
super();
log = LogFactory.getLog(MessageDaoImpl.class);
}
#SuppressWarnings("unchecked")
#Transactional(readOnly = true, propagation = Propagation.REQUIRED)
public List<Message> listMessages()
{
try
{
return (List<Message>) sessionFactory.getCurrentSession()
.createCriteria(Message.class).list();
} catch (Exception e)
{
log.fatal(e.getMessage());
return null;
}
}
#SuppressWarnings("unchecked")
#Transactional(readOnly = false, propagation = Propagation.REQUIRED)
public void SaveOrUpdateMessage(Message message)
{
try
{
Session mySession = sessionFactory.getCurrentSession();
mySession.save(message);
mySession.flush();
} catch (Exception e)
{
log.fatal(e.getMessage());
}
}
}
Here is my main class:
public static void main(String[] args)
{
ApplicationContext context = new AnnotationConfigApplicationContext(HelloWorldConfig.class);
MessageService mService = context.getBean(MessageService.class);
HelloWorld helloWorld = context.getBean(HelloWorld.class);
/**
* Date: 4/26/13 / 9:26 AM
* Comments:
*
* I added Log4J to the example.
*/
LOGGER.debug("Message from HelloWorld Bean: " + helloWorld.getMessage());
Message message = new Message();
message.setMessage(helloWorld.getMessage());
//
mService.SaveMessage(message);
helloWorld.setMessage("I am in Staten Island, New York");
LOGGER.debug("Message from HelloWorld Bean: " + helloWorld.getMessage());
}
}
Here is my DatabaseConfig:
public class DatabaseConfig
{
private static final Logger LOGGER = getLogger(DatabaseConfig.class);
#Autowired
Environment env;
#Bean
public DataSource dataSource() {
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
EmbeddedDatabase db = builder.setType(EmbeddedDatabaseType.HSQL).
addScript("schema.sql").build();
return db;
}
#Bean
public DataSource hsqlDataSource() {
BasicDataSource ds = new BasicDataSource();
try {
ds.setDriverClassName("org.hsqldb.jdbcDriver");
ds.setUsername("sa");
ds.setPassword("");
ds.setUrl("jdbc:hsqldb:mem:mydb");
}
catch (Exception e)
{
LOGGER.error(e.getMessage());
}
return ds;
}
#Bean
public SessionFactory sessionFactory()
{
LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean();
factoryBean.setDataSource(hsqlDataSource());
factoryBean.setHibernateProperties(getHibernateProperties());
factoryBean.setPackagesToScan(new String[]{"com.xxxxx.HelloSpringJavaBasedJavaConfig.model"});
try
{
factoryBean.afterPropertiesSet();
} catch (IOException e)
{
LOGGER.error(e.getMessage());
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
return factoryBean.getObject();
}
#Bean
public Properties getHibernateProperties()
{
Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
hibernateProperties.setProperty("hibernate.show_sql", env.getProperty("hibernate.show_sql"));
hibernateProperties.setProperty("hibernate.use_sql_comments", env.getProperty("hibernate.use_sql_comments"));
hibernateProperties.setProperty("hibernate.format_sql", env.getProperty("hibernate.format_sql"));
hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
hibernateProperties.setProperty("hibernate.generate_statistics", env.getProperty("hibernate.generate_statistics"));
hibernateProperties.setProperty("javax.persistence.validation.mode", env.getProperty("javax.persistence.validation.mode"));
//Audit History flags
hibernateProperties.setProperty("org.hibernate.envers.store_data_at_delete", env.getProperty("org.hibernate.envers.store_data_at_delete"));
hibernateProperties.setProperty("org.hibernate.envers.global_with_modified_flag", env.getProperty("org.hibernate.envers.global_with_modified_flag"));
return hibernateProperties;
}
#Bean
public HibernateTransactionManager hibernateTransactionManager()
{
HibernateTransactionManager htm = new HibernateTransactionManager();
htm.setSessionFactory(sessionFactory());
htm.afterPropertiesSet();
return htm;
}
}
and here is what I am getting to the console:
Exception in thread "main" org.hibernate.AssertionFailure: null id in com.xxx.HelloSpringJavaBasedJavaConfig.model.Message entry (don't flush the Session after an exception occurs)
Here is my message model bean:
#Entity
#Table(name = "messages")
public class Message
{
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.AUTO)
private String id;
#Column(name = "message")
private String message;
public String getId()
{
return id;
}
public void setId(String id)
{
this.id = id;
}
public String getMessage()
{
return message;
}
public void setMessage(String message)
{
this.message = message;
}
#Override
public String toString()
{
return "Message{" +
"id='" + id + '\'' +
", message='" + message + '\'' +
'}';
}
}
This relates to the version of hsql being used probably the version causing issue was 1.8 with hibernate 4. Need to use 2.2.9 instead
You can't use a String with #GenerateValue with the Strategy GenerationType.AUTO since it uses sequence generator and those can't be used with non-numerical values. You have to set it yourself. Use an Integer or Long if you want it to be generated for you.
Hibernate docs
Or use an id generator that uses string values
#Id
#GeneratedValue(generator="system-uuid")
#GenericGenerator(name="system-uuid", strategy = "uuid")
it was a version issues. I updated the versions and now everything works
I had the same issue after I upgraded hibernate to version 4.2.8 .Looking in the logs, I noticed that the sql query generated by hibernate tried to insert a record with a null primary key. The field was annotated just with: #Id #GeneratedValue
Upgrading hsqldb to version 2.2.9 made this disappear just like Denis said and I am very thankful to him for the reply.
It seems very likely that this issue is related to attempting to use a Session which has already signaled an error. As Sotirios mentioned, it is a bad idea to catch exceptions in your DAO, and if you do, it is critical that you re-throw them.
Normally, once you catch a Hibernate exception, you must roll back your transaction and close the session as the session state may no longer be valid (Hibernate core documentation).
If the Session throws an exception, including any SQLException, immediately rollback the database transaction, call Session.close() and discard the Session instance. Certain methods of Session will not leave the session in a consistent state. No exception thrown by Hibernate can be treated as recoverable. Ensure that the Session will be closed by calling close() in a finally block.
Since you're using Spring, most of that doesn't apply to you, but the exception message you are seeing indicates that the actual cause of your problem probably was related to catching an exception and then continuing to use the same session.
I have 2 methods:
public static Ticket issueTicket(User user,Service service,String[] seats) {
Session ticSess= DB.factory.openSession();
ticSess.beginTransaction();
Date d= new Date();
Ticket ticket=new Ticket(d, service, user);
ticSess.save(ticket);
ticSess.getTransaction().commit();
int seatCount=seats.length;
for (int i=0;i<seatCount;i++){
int seatID=Integer.parseInt(seats[i]);
Seat seat=getSeatByID(seatID);
seat.setTicket(ticket);
ticSess.update(seat);
}
return ticket;
}
and,
public static Seat getSeatByID(int seatID) {
Session proSess = DB.factory.openSession();
proSess.beginTransaction();
Seat c = (Seat) (proSess.load(Seat.class, seatID));
proSess.getTransaction().commit();
return c;
}
when I call issueTicket method I get:
illegally attempted to associate a proxy with two open Sessions
and If I close the session in getSeatByID method there will be another error telling that the session is closed. Here is the Stack Trace:
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:164)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:285)
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185)
at ir.ac.shirazu.cse.Terminal.Seat_$$_javassist_9.setTicket(Seat_$$_javassist_9.java)
at ir.ac.shirazu.cse.Database.DB.issueTicket(DB.java:231)
Try closing proSess in getSeatByID() before returning. Currently the Seat indeed remains attached to session opened in getSeatByID().
I got same problem . But after using singleton pattern for session i'm done. I'm using Hibernate 4.2.x.
This is my session class is used to get sessions for DB transactions etc.
public class SessionClass {
static Session session = PoolManager.getSession();
public static Session getSession() {
if (session != null || session.isOpen()) {
return session;
} else {
session = PoolManager.getSession();
return session;
}
}
}
Hibernate Helper Class I'm using.
public class PoolManager {
private static final SessionFactory sessionFactory;
private static final ServiceRegistry serviceRegistry;
static {
try {
// Create the SessionFactory from standard (hibernate.cfg.xml)
// config file.
Configuration configuration = new Configuration();
configuration.configure();
serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
} catch (Throwable ex) {
// Log the exception.
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static Session getSession() {
return sessionFactory.openSession();
}
}
I ran into this issue when trying to associate a entity from a Envers Session.
Fixed that by "refreshing" said entity (retrieving it on my non-Envers session via PK fetch) before bubbling it up to my algorithm.
use session.opensession().get(.....).. instead of session.opensession().load(.....)
what if you do a proSess.evict(c) before committing proSess?
Context
I'm creating a database environment where I'd like to split data in several different schemas to be used for different groups of users. Although, one of these databases should be shared to everyone due to it contains common entities.
Suppose databases:
DB1 - Common entities;
Wheels entity
DB2 - Group "A";
Cars entity
DB3 - Group "B";
Motorcycles entity
I have three different projects:
Project 1:
Wheels bean
Project 2:
Cars constructor
Project 3:
Motorcycles constructor
Problem
I'm trying to access wheels (Project 1) from projects/schemas (2,"A") and (3,"B")
First question: Is it possible?
Second: How can I do it?
hibernate.cfg.xml in project 2 is configured to
<property name="hibernate.connection.url">jdbc:mysql://99.999.999.99:3306/DB2</property>
This necessarily must restrict all the connections to DB2, or there's another way to add a new connection or work with all databases in 3306 port, or at least DB1?
Mapping the entities from project1 in project 2 seems not to be succeeded too, like:
<mapping class="com.company.project1.Wheels"
package="com.company.project1.Wheels" resource="com/company/project1/Wheels.hbm.xml"/>
Configuration
Eclipse Indigo
MySql 5.5
Hibernate 3.0 (mapping through xml instead annotations)
Win 7
Thanks for helping!
You can use #Table(catalog="") to specify database to which they belong to and then also can make relation across database.
in your case Wheel maps to DB1, Car to DB2 and MotorCycle to DB3 using catalog attribute.
i have used this solution with MySQL and MSSQL and works perfectly fine. only constraint this has all three DB has to be in same database server and user which is being used to access db should have appropriate permission to all DB.
As this solution just adds schema name against table in all queries.
I would divide my project in multiple self sustained projects. The Wheel project will be self sufficient project which takes care of Wheel entity.
Project 1: Wheel
This project will define Hibernate entities and DAO to access / modify wheel definitions.
Also I would configure a separate datasource in this project which points to DB1.
Entity classes:
#Entity
public class Wheel {
}
DAO classes:
#Repository
public class WheelDAO {
#Persistence
private EntityManager em;
}
Basically the idea is to separate application at DAO level. And manage transactions at Service level. Imaging WheelDAO (wired to DB1 datasource) and CarDAO (wired to DB2 datasource) and inject these in CarService.
DB1 DB2 DB2
| | |
WheelDAO CarDAO MotorcycleDAO
\_____________/ |
\_____|__________________________/
| |
| |
CarService MotorCycleService
I suggest to use Spring as IOC container to manage these dependency. Although you can achieve this without using Spring too.
What you need is just a db connection factory which allows you to use db that you want when you need it.
Take a look at the class below which you can adapte to resolve your issue
import java.net.URL;
import java.util.HashMap;
import javax.security.auth.login.Configuration;
public class HibernateUtil {
private static Log log = LogFactory.getLog(HibernateUtil.class);
private static HashMap<String, SessionFactory> sessionFactoryMap = new HashMap<String, SessionFactory>();
public static final ThreadLocal sessionMapsThreadLocal = new ThreadLocal();
public static Session currentSession(String key) throws HibernateException {
HashMap<String, Session> sessionMaps = (HashMap<String, Session>) sessionMapsThreadLocal.get();
if(sessionMaps == null) {
sessionMaps = new HashMap();
sessionMapsThreadLocal.set(sessionMaps);
}
// Open a new Session, if this Thread has none yet
Session s = (Session) sessionMaps.get(key);
if(s == null) {
s = ((SessionFactory) sessionFactoryMap.get(key)).openSession();
sessionMaps.put(key, s);
}
return s;
}
public static Session currentSession() throws HibernateException {
return currentSession("");
}
public static void closeSessions() throws HibernateException {
HashMap<String, Session> sessionMaps = (HashMap<String, Session>) sessionMapsThreadLocal.get();
sessionMapsThreadLocal.set(null);
if(sessionMaps != null) {
for(Session session : sessionMaps.values()) {
if(session.isOpen())
session.close();
}
;
}
}
public static void closeSession() {
HashMap<String, Session> sessionMaps = (HashMap<String, Session>) sessionMapsThreadLocal.get();
sessionMapsThreadLocal.set(null);
if(sessionMaps != null) {
Session session = sessionMaps.get("");
if(session != null && session.isOpen())
session.close();
}
}
public static void buildSessionFactories(HashMap<String, String> configs) {
try {
// Create the SessionFactory
for(String key : configs.keySet()) {
URL url = HibernateUtil.class.getResource(configs.get(key));
SessionFactory sessionFactory = new Configuration().configure(url).buildSessionFactory();
sessionFactoryMap.put(key, sessionFactory);
}
} catch(Exception ex) {
ex.printStackTrace(System.out);
log.error("Initial SessionFactory creation failed.", ex);
throw new ExceptionInInitializerError(ex);
} // end of the try - catch block
}
public static void buildSessionFactory(String key, String path) {
try {
// Create the SessionFactory
URL url = HibernateUtil.class.getResource(path);
SessionFactory sessionFactory = new Configuration().configure(url).buildSessionFactory();
sessionFactoryMap.put(key, sessionFactory);
} catch(Throwable ex) {
log.error("Initial SessionFactory creation failed.", ex);
throw new ExceptionInInitializerError(ex);
} // end of the try - catch block
}
public static void closeSession(String key) {
HashMap<String, Session> sessionMaps = (HashMap<String, Session>) sessionMapsThreadLocal.get();
if(sessionMaps != null) {
Session session = sessionMaps.get(key);
if(session != null && session.isOpen())
session.close();
}
}
} // end of the class
http://www.java-forums.org/