How can I translate JPA xml configuration into a java class? - java

I want to a configure JPA in a java class (not using the usual persistence.xml approach)
Here is an example of what I'm doing:
public SessionFactory getSessionFactory(){
Configuration configuration=new Configuration();
Properties settings= new Properties();
settings.put(Environment.DRIVER, "");
settings.put(Environment.URL, "");
settings.put(Environment.USER, "");
settings.put(Environment.PASS, "");
settings.put(Environment.DIALECT, "");
settings.put(Environment.SHOW_SQL, "true");
settings.put(Environment.DEFAULT_SCHEMA, "");
configuration.setProperties(settings);
configuration.addAnnotatedClass(Passenger.class);
ServiceRegistry serviceRegistry=new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties()).build();
sessionFactory=configuration.buildSessionFactory(serviceRegistry);
}

If you cannot (or don't want) use the standard XML configuration, you can bootstrap JPA via a custom implementation. Here is an example.
If you provide more info about your desired result (dialect, persistence unit name etc.) I can give you a more detailed example.

Related

How to create SessionFactory bean when datasource is defined but not xml but by configuration bean

Hibernate 5.4
The dialect is known, I need to implement the following method :
#Bean
public org.hibernate.SessionFactory sessionFactory(DataSource dataSource) {
// hibernate.dialect = "org.hibernate.dialect.PostgreSQL95Dialect"
// ???
}
Maybe creating one via a Configuration would work for you, as descibed here:
Create Sessionfactory in Hibernate
Configuration cfg = new Configuration()...
.setProperty("hibernate.connection.username", "myuser");
.setProperty("hibernate.connection.password", "mypassword")
.setProperty("hibernate.connection.url", "jdbc:mysql://localhost:3306/hibernate_example")
SessionFactory sessionFactory = cfg.buildSessionFactory();
Or you choose to use the Spring LocalSessionFactory-Class like so:
lsfb = new LocalSessionFactoryBean() [from hib5-package]
lsfb.setDataSource( yourDS );
return lsfb.getObject();
Setting the Datasource this might help:
Luiggi Mendoza on SO (How can I set Datasource when I'm creating Hibernate SessionFactory?
)
But if you use a custom data source provider like Apache DBCP or BoneCP and you don't want to use a dependency injection framework like Spring, then you may inject it on the StandardServiceRegistryBuilder before creating the SessionFactory...

Hibernate - non-working code an what is a service-registry

I just got through the book "Just Hibernate" from O'Reilly. Some code isn't really explained fully but just given without complete description.
This code for example:
public class BasicMovieManager {
private SessionFactory sessionFactory = null;
// Creating SessionFactory using 4.2 version of Hibernate
private void initSessionFactory(){
Configuration config = new Configuration().configure();
// Build a Registry with our configuration properties
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(
config.getProperties()).buildServiceRegistry();
// create the session factory
sessionFactory = config.buildSessionFactory(serviceRegistry);
}
...
}
I just wanted to copy the code to my Hibernate-experiments, but the current stable Hibernate-version 5.2 doesn't know the class ServiceRegistryBuilder. What is a service-registry and how do I have to change the code to work with the current Hibernate-version?
The code was used to create a SessionFactory with Hibernate 4.x
The similar code for Hibernate 5.x would be something like:
StandardServiceRegistry standardRegistry =
new StandardServiceRegistryBuilder().configure("hibernate.cfg.xml").build();
Metadata metaData =
new MetadataSources(standardRegistry).getMetadataBuilder().build();
sessionFactory = metaData.getSessionFactoryBuilder().build();
As you can see, in Hibernate 5 StandardServiceRegistry class is used. If you don't have a hibernate.cfg.xml file just use configure() method with no arguments.
See this article for further details.

Hibernate ImprovedNamingStrategy doesn't work

I have a database with columns naming using snakecase and entities where columns named in camelcase. The project was written using spring boot and had this configuration:
#Primary
#Bean
public LocalContainerEntityManagerFactoryBean mainEntityManagerFactory(
#Qualifier("mainDataSource") DataSource mainDataSource,
#Qualifier("mainJpaProperties") JpaProperties mainJpaProperties) {
AbstractJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
adapter.setShowSql(mainJpaProperties.isShowSql());
adapter.setDatabase(mainJpaProperties.getDatabase());
adapter.setDatabasePlatform(mainJpaProperties.getDatabasePlatform());
adapter.setGenerateDdl(mainJpaProperties.isGenerateDdl());
Map<String, Object> jpaProperties = new HashMap<>();
jpaProperties.putAll(mainJpaProperties.getHibernateProperties(mainDataSource));
jpaProperties.put("jpa.hibernate.naming_strategy", "org.springframework.boot.orm.jpa.hibernate.SpringNamingStrategy");
return new EntityManagerFactoryBuilder(adapter, mainJpaProperties, persistenceUnitManager)
.dataSource(mainDataSource)
.packages(Employee.class)
.properties(jpaProperties)
.persistenceUnit("main")
.jta(false)
.build();
}
this is application.properties content:
jpa.hibernate.hbm2ddl.auto=none
jpa.hibernate.ddlAuto=none
jpa.hibernate.naming_strategy = org.springframework.boot.orm.jpa.hibernate.SpringNamingStrategy
jpa.generateDdl=false
jpa.showSql=false
jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL9Dialect
Now I can't use spring boot and trying to convert configuration:
#Primary
#Bean
public LocalContainerEntityManagerFactoryBean mainEntityManagerFactory(
#Qualifier("mainDataSource") DataSource mainDataSource
) {
AbstractJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
adapter.setShowSql(Boolean.valueOf(environment.getProperty("jpa.showSql")));
adapter.setDatabase(Database.POSTGRESQL);
adapter.setDatabasePlatform(environment.getProperty("jpa.hibernate.dialect"));
adapter.setGenerateDdl(Boolean.valueOf(environment.getProperty("jpa.generateDdl")));
Properties jpaProperties = new Properties();
jpaProperties.put("jpa.hibernate.dialect", environment.getProperty("jpa.hibernate.dialect"));
jpaProperties.put("hibernate.naming_strategy", "main.util.NamingStrategy");
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setDataSource(mainDataSource);
factoryBean.setJpaVendorAdapter(adapter);
factoryBean.setPersistenceUnitName("main");
factoryBean.setPersistenceUnitManager(persistenceUnitManager);
factoryBean.setJpaProperties(jpaProperties);
factoryBean.setPackagesToScan(packageToScan);
factoryBean.afterPropertiesSet();
return factoryBean;
}
main.util.NamingStrategy is just a copypaste of org.springframework.boot.orm.jpa.hibernate.SpringNamingStrategy.
When I trying to run it it looks like that this naming strategy doesn't work because I get an error:
org.hibernate.AnnotationException:
Unable to create unique key constraint (emp_address_id, year, yearNumber)
on table employeedata:
database column 'emp_address_id' not found.
Make sure that you use the correct column name which depends
on the naming strategy in use
(it may not be the same as the property name in the entity,
especially for relational types)
How can I make this work without spring boot?
Just to put it explicitly(as i had to spend some time figuring it out from Maciej's answer), this works for me on Hibernate 5.x:
properties.put("hibernate.physical_naming_strategy", "org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy");
jpa.hibernate.naming_strategy property key is used only in Spring Boot's configuration.
When you configure hibernate by yourself you should use Hibernate properties instead. Proper name of Hibernate naming strategy property key is
hibernate.ejb.naming_strategy
Try to replace it in your jpaProperties object:
Properties jpaProperties = new Properties();
jpaProperties.put("hibernate.dialect", environment.getProperty("jpa.hibernate.dialect")); //jpa dialect property key is different too
jpaProperties.put("hibernate.ejb.naming_strategy", "main.util.NamingStrategy");
List of all miscellaneous properties:
https://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html_single/#configuration-misc-properties
I am assuming that you only removed Spring Boot and you are still using Hibernate 4.x (in Hibernate 5.x NamingStrategy was replaced with ImplicitNamingStrategy and PhysicalNamingStrategy)
For hibernate 5.x you should use org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNam‌​ingStrategy and default Hibernate's ImplicitNamingStrategy:
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-1.4-Release-Notes#naming-strategy
Configuration key for this physical naming strategy is: hibernate.physical_naming_strategy

Dao Test for Dropwizard

Trying to write Dao Test cases for Dropwizard application.
I have implemented my own version to AbstractDaoTest class which has nothing todo with Dropwizard's configuration. Wondering if I can use Dropwizard's hibernate configuration and get session factory from Dropwizard's HibernateBundle.
public AbstractDaoTest() {
Configuration config=new Configuration();
config.setProperty("hibernate.connection.url","jdbc:mysql://127.0.0.1/testme");
config.setProperty("hibernate.connection.username","haha");
config.setProperty("hibernate.connection.password","haha");
config.setProperty("hibernate.connection.driver_class","com.mysql.jdbc.Driver");
config.setProperty("hibernate.current_session_context_class","thread");
config.setProperty("hibernate.show_sql", "true");
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(config.getProperties()).build();
sessionFactory = config.buildSessionFactory(serviceRegistry);
}
Is there a way I can get hold of HibernateBundle of Dropwizard in my AbstarctDaoTest class?

Access SSL-Parameters in connections via Hibernate

I am using a hibernate java application which uses a sessionfactory to create connections and sessions. As i am using it with a postgresql database i pass the proper jdbc connectionstring to build the sessionfactory and get my sessions from it afterwards. The only thing im able to access is the jdbc4connection.
How am i able to read which ciphersuite is used within the secured connection, which SSL protocol is used etc?
Here is how i initialize my sessionfactory:
Configuration configuration = new Configuration();
Properties p = configuration.getProperties();
p.setProperty("hibernate.connection.url","jdbc:postgresql://127.0.0.1:5432/postgres?ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory");
p.setProperty("hibernate.connection.username", "myusername");
p.setProperty("hibernate.connection.password", "mypassword");
p.setProperty("hibernate.connection.driver_class",
"org.postgresql.Driver");
p.setProperty("hibernate.dialect",
"org.hibernate.dialect.PostgreSQLDialect");
ServiceRegistry serviceRegistryWebOnkys = new StandardServiceRegistryBuilder()
.applySettings(p).build();
SessionFactory sessionFactory = configuration
.buildSessionFactory(serviceRegistryWebOnkys);
If you can find out how to do it with via regular JDBC (I don't know how it's done), then you can do the same thing with Hibernate.
session.doWork(new Work() {
#Override
public void execute(Connection connection) throws SQLException {
// access the connection here and perform regular jdbc operations.
}
});
This is what I had to do when I had set some Oracle specific properties that could be set only on "OracleConnection.java" instances.
oracle.jdbc.driver.OracleConnection oc = (oracle.jdbc.driver.OracleConnection) connection.getMetaData().getConnection()

Categories

Resources