How to get datasource from Hibernate Configuration - java

I would like to get a datasource from a hibernate Configuration programmaticaly. Here is the code that I wrote :
public static DataSource getDatasource(Configuration configuration){
ServiceRegistry registry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
SessionFactoryImpl session = (SessionFactoryImpl)configuration.buildSessionFactory(registry);
DatasourceConnectionProviderImpl provider = (DatasourceConnectionProviderImpl) session.getConnectionProvider();
return provider.getDataSource();
}
But I got an exception while running the application :
Exception in thread "main" org.hibernate.HibernateException: Missing table: CONTACTS
at org.hibernate.cfg.Configuration.validateSchema(Configuration.java:1281)
at org.hibernate.tool.hbm2ddl.SchemaValidator.validate(SchemaValidator.java:155)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:508)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1769)
at com.heavenize.Migrations.getDatasource(Migrations.java:30)
at com.heavenize.Migrations.main(Migrations.java:60)
I am performing some database migration and I need the datasource to pass to my migration tool programmaticaly.
It seems that problem come with the fact that buildSessionFactory because hibernate is trying to map the entities with the tables in the database.
The property "hibernate.hbm2ddl.auto" is set to validate.
Is there a better way to get the datasource?

The error that you are getting has nothing to do with retrieving the DataSource. It is because Hibernate is validating the data model with the database and doesn't find it to be in syncrhonization. You can remove the hibernate.hbm2ddl.auto property completely, which will then default it to none and there won't be any validation.

Related

GenerationType.SEQUENCE breaks spring application

I really want to try batching insert operations for myself in spring, but there is a huge problem that is driving me insane.
As written on web, Hibernate will silently disable batching queries whenever you have entity with GenerationType.IDENTITY (https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#batch-session-batch).
Therefore, I have tried to change my entities generationType to Sequence, but whenever i do this, my project seems to be completely broken (it won't even start).
I start to think that there are several problems in compatibility of postgresql and batching operations in spring.
Could you please explain to me, why is that?
My datasource configuration method:
#Bean
public DataSource dataSource() {
Properties props = new Properties();
props.setProperty("dataSourceClassName", "org.postgresql.ds.PGSimpleDataSource");
props.setProperty("dataSource.user", "tesstuser");
props.setProperty("dataSource.password", "12345");
props.setProperty("dataSource.databaseName", "testdatabase");
props.put("dataSource.logWriter", new PrintWriter(System.out));
HikariConfig config = new HikariConfig(props);
HikariDataSource dataSource = new HikariDataSource(config);
return ProxyDataSourceBuilder.create(dataSource)
.name("Batch-Insert-Logger")
.asJson().countQuery().logQueryToSysOut().build();
}
Error message:
org.hibernate.exception.SQLGrammarException: could not extract ResultSet
PostgreSql exception:
org.postgresql.util.PSQLException: ERROR: relation "hibernate_sequence" does not exist

hibernate.cfg.xml to java configuration

i am trying to create a sample hibernate program, i have working code of xml based hibernate configurations so trying to convert it in annotation and java configuration based.
i successfully converted Employee.hbm.xml to annotation (#Entity in Employee.class) but not able to do same for hibernate.cfg.xml.
Configuration cfg = new AnnotationConfiguration().addAnnotatedClass(com.hibernate.apple.Employee.class);
cfg.setProperty("hibernate.hbm2ddl.auto","update");
cfg.setProperty("hibernate.connection.driver_class","com.mysql.jdbc.Driver");
cfg.setProperty("hibernate.dialect","org.hibernate.dialect.MySQLDialect");
cfg.setProperty("hibernate.connection.url","jdbc:mysql://localhost/DataBase");
cfg.setProperty("hibernate.connection.username","xxx");
cfg.setProperty("hibernate.connection.password","xxx");
Session s = cfg.configure().buildSessionFactory().openSession();
Transaction t = s.beginTransaction();
t.begin();
....
but its giving error
Exception in thread "main" org.hibernate.HibernateException: /hibernate.cfg.xml not found
above code is to replace the hibernate.hbm.xml , then why it is asking for the same , am i missing something?.
You call the method configure and its documentation gives following information:
Use the mappings and properties specified in an application resource named hibernate.cfg.xml.
If you don't want to use this file, create your session without calling configure.
Session s = cfg.buildSessionFactory().openSession();
By the way, AnnotationConfiguration is from Hibernate 3. Hibernate 4 and 5 do not have this class and therefore think about updating your current hibernate version.

Perform native SQL Query during Spring startup

I'm using Spring and Hibernate with an automatically generated database (for that I have set "hibernate.hbm2ddl.auto" to "update" in the JPA configuration properties).
I also have a class annotated #Configuration with a #PostConstruct method that is called on application startup after the database has been created or updated. This is where I setup the database with some default data if it's empty (first launch).
I would like to execute some custom native SQL queries at this moment. These queries won't return anything, they're just configuration stuff (like creating additional indexes or extensions).
Currently I'm stuck on creating a SessionFactory in order to create a new Hibernate Session. I've tried auto wiring it, but it doesn't work :
#Autowired
SessionFactory sessionFactory;
Gives me: Field sessionFactory in ... required a bean of type 'org.hibernate.SessionFactory' that could not be found.
I understand that I probably need to configure it elsewhere, but I don't know where. Several answers on SO use an xml configuration file, but I'm not using any configuration file so I can't do it that way.
Is there a way Spring can create the SessionFactory with the appropriate configuration ?
You don't even need to access SessionFactory. Please just put your scripts into a file src/main/resources/scripts/myscript.sql. You can then do the following with Spring:
#Component
public class Startup {
#Autowired
private DataSource dataSource;
#PostConstruct
public void runNativeSql() {
ClassPathResource resource = new ClassPathResource("scripts/myscript.sql");
try(Connection connection = dataSource.getConnection()) {
ScriptUtils.executeSqlScript(connection, resource);
} catch (SQLException | ScriptException e) {
//LOG
}
}
}
You can autowire the JPA EntityManager as:
#PersistenceContext
EntityManager entityManager;
If you really need a Hibernate Session and are using using JPA 2.1, the Session can be obtained from the EntityManager as:
entityManager.unwrap(Session.class);

OpenJPA says: You have supplied colums for FooBar but this mapping cannot have columns in this context

I have some Java entity classes that are working well in my production code. I am writing an automated test for this application where I am reusing the very same classes.
When the test application is creating its entity manager this way:
Properties props = new Properties();
props.setProperty("provider", "org.apache.openjpa.persistence.PersistenceProviderImpl");
props.setProperty(...);
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("foobar-upgrade-restful-test", props);
EntityManager entityManager = entityManagerFactory.createEntityManager();
The applications throws an error message telling that:
Caused by: <openjpa-2.2.0-r422266:1244990 fatal user error> org.apache.openjpa.persistence.ArgumentException: You have supplied columns for "com.foo.bar.server.commontypes.job.CompositeJob", but this mapping cannot have columns in this context.
at org.apache.openjpa.jdbc.meta.MappingInfo.assertNoSchemaComponents(MappingInfo.java:382)
at org.apache.openjpa.jdbc.meta.strats.FlatClassStrategy.map(FlatClassStrategy.java:51)
at org.apache.openjpa.jdbc.meta.ClassMapping.setStrategy(ClassMapping.java:392)
at org.apache.openjpa.jdbc.meta.RuntimeStrategyInstaller.installStrategy(RuntimeStrategyInstaller.java:56)
at org.apache.openjpa.jdbc.meta.MappingRepository.prepareMapping(MappingRepository.java:411)
at org.apache.openjpa.meta.MetaDataRepository.preMapping(MetaDataRepository.java:762)
at org.apache.openjpa.meta.MetaDataRepository.resolve(MetaDataRepository.java:651)
... 72 more
I do not really understand the error message as the same entity bean is working in the application under Glassfish and the persistence.xml is also almost identical. (In the test I use RESOURCE_LOCAL tx instead of JTA but I doubt that it has relation with this error.
Do you have any idea what's wrong?
The error indicates that there is a problem with the mapping information that you provided for com.foo.bar.server.commontypes.job.CompositeJob.
I'm guessing the reason it works for JTA, but not resource local most likely has to do with some oddity in the way that metadata is loaded / processed in the different environments. It would be helpful if you post the relevant mapping data from your Entity.

transaction is not getting roll backed with jta transaction manager

I am new to Spring and hibernate please help,
I am using (Jboss 6.0 Final as Server)
org.springframework.transaction.jta.JtaTransactionManager
as bean with properties set
transactionManagerName as java:/TransactionManager and
userTransactionName as java:comp/UserTransaction.
In code I have set jtaTxManager property thr setters.
Then
javax.transaction.TransactionManager tx = jtaTxManager.getTransactionManager();
and then transaction is started using tx.begin() statement.
I have used sessionFactory.getCurrentSession() to get session of hibernate
at last I have used
tx.commit()
I am using hibernate to save multiple records within jta transaction
but If in between any database error occurs between some record like constraint violation exception getting thrown on tx.commit() which is javax.transaction.RollbackException which when catch I used to call tx.rollback() but my transaction is not getting rollback and getting following exception on tx.rollback().I have not set any type auto commit property in hibernate properties.
But my first of records in gets saved in database ideally they should not saved but while rollback this exception occurs so i think that's why they are getting saved.
java.lang.IllegalStateException: BaseTransaction.rollback - [com.arjuna.ats.internal.jta.transaction.arjunacore.notx] [com.arjuna.ats.internal.jta.transaction.arjunacore.notx] no transaction!
at com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.rollback(BaseTransaction.java:158)
at com.arjuna.ats.jbossatx.BaseTransactionManagerDelegate.rollback(BaseTransactionManagerDelegate.java:114)
This issue was due to datasource configuration, forgot to mentioned earlier,
Removed from application-context.xml
org.springframework.jdbc.datasource.DriverManagerDataSource
and rather than this, used jndi datasorce of jboss configured in oracle-xa-ds.xml
The Javadoc states that the RollbackException gets thrown when the transaction has been rolledback instead of commited - you don't have to rollback it manually in such a case, I think.
http://download.oracle.com/javaee/6/api/javax/transaction/Transaction.html#commit%28%29

Categories

Resources