hibernate.cfg.xml to java configuration - java

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.

Related

LazyInitializationException in a Spring Transaction

In a Spring Boot project I am working at I added the Hibernate ORM plugin to enable lazy loading for #Lob fields in my entity, this didn't work out of the box for DB2. The lazy loading works, when I retrieve the object the lob field isn't loaded yet. But now a new problem occurs, when I do want to get the blob field I get a LazyInitializationException. Now I did some debugging and Google searches. I tried to add #Transactional to the method and to the classes, I also tried multiple propagation options, but nothing works.
I also tried to load the object directly using the EntityManager, but that also gives the same exception:
Object object = entityManager.find(Object.class, id);
object.getLobField();
The full exception that is thrown is:
org.hibernate.LazyInitializationException: Unable to perform requested lazy initialization [package.Object.lobField] - no session and settings disallow loading outside the Session
You need to activate in your application.yml
spring:
jpa:
properties:
hibernate:
enable_lazy_load_no_trans: true
This will allow lazy loading to work outside the session that created the object that has properties that are lazy loaded.
Reference: https://www.baeldung.com/hibernate-lazy-loading-workaround, Solve Hibernate Lazy-Init issue with hibernate.enable_lazy_load_no_trans and https://vladmihalcea.com/the-hibernate-enable_lazy_load_no_trans-anti-pattern/

Wait for database connection in Spring Boot without an exception

I want to create a microservice with Spring Boot. For persistence i use a mariadb database. To wait for the database which is running in a docker container, i implemented the following code like shown here:
#Bean
public DatabaseStartupValidator databaseStartupValidator(DataSource dataSource) {
var dsv = new DatabaseStartupValidator();
dsv.setDataSource(dataSource);
dsv.setTimeout(60);
dsv.setInterval(7);
dsv.setValidationQuery(DatabaseDriver.MYSQL.getValidationQuery());
return dsv;
}
The code is working very well, my application is now waiting for the database connection. But i get an exception at startup of the application:
java.sql.SQLNonTransientConnectionException: Could not connect to Host ....
...
...
...
In the next line i get an information, that it will wait for the database:
021-04-07 21:29:40.816 INFO 16569 --- [ main] o.s.j.support.DatabaseStartupValidator : Database has not started up yet - retrying in 7 seconds (timeout in 57.65 seconds)
After that the application is starting as expected. So i think everything is working fine, but what i have to do to suppress the Exception? In the linked article it should work without an exception. Do i have to implement the "dependsOnPostProcessor" function? Which dependency i have to use? Sorry, possible a dumb question, i am new to spring boot.
to get rid of that exception you can state the below directive in your application.properties file:
logging.level.com.zaxxer.hikari=OFF
Keep in mind that if the application will not be able to get in contact with the db your spring crashes after a while due to that exception. In addition the above directive prevent you to see any logging activity related to Hikari.
In summary you hide the appearance of the exception until it is possible before the application dies due to timeout.
hoping I clarified a bit the case
Yes indeed you need to add the "depends-on" for the beans that rely on the data source. Note the following part of the documentation:
To be referenced via "depends-on" from beans that depend on database startup, like a Hibernate SessionFactory or custom data access objects that access a DataSource directly.
If I understand it well, this means that beans such as an EntityManagerFactory which rely on the database will now have to go through the DatabaseStartupValidator bean and wait for the DB startup. I don't know what caused your exception, but usually there is an EntityManagerFactory involved, so try adding the DependsOn on this object at least.
This is how the linked article is doing it:
#Bean
public static BeanFactoryPostProcessor dependsOnPostProcessor() {
return bf -> {
// Let beans that need the database depend on the DatabaseStartupValidator
// like the JPA EntityManagerFactory or Flyway
String[] flyway = bf.getBeanNamesForType(Flyway.class);
Stream.of(flyway)
.map(bf::getBeanDefinition)
.forEach(it -> it.setDependsOn("databaseStartupValidator"));
String[] jpa = bf.getBeanNamesForType(EntityManagerFactory.class);
Stream.of(jpa)
.map(bf::getBeanDefinition)
.forEach(it -> it.setDependsOn("databaseStartupValidator"));
};
}
You may not necessarily have Flyway configured, but the main thing to note is the dependency itself is referenced by the bean name databaseStartupValidator which is the name of the method that creates the bean.

How to get datasource from Hibernate Configuration

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.

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