I have set up integration tests for a spring boot project using test containers (sets up a docker instance with postgresql). The tests work great if the repositories that I am testing against do not use native queries. However, whenever a repository contains a native query I get the following error: ERROR: relation "my_table_here" does not exist. How do I get my test configuration to work to allow native queries?
Below is my test set up:
#RunWith(SpringRunner.class)
public class TestPostgresql {
#ClassRule
public static PostgreSQLContainer postgreSQLContainer = PostgresDbContainer.getInstance();
/**
* ************ REPOSITORIES ************
*/
#Autowired
NativeQueryRepository nativeQueryRepository;
#TestConfiguration
#EnableJpaAuditing
#EnableJpaRepositories(
basePackageClasses = {
NativeQueryRepository.class
})
#ComponentScan(
basePackages = {
"com.company.project.package.repository"
}
)
static class PostgresConfiguration {
/**
* ************ DATABASE SETUP ************
*/
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setUrl(postgreSQLContainer.getJdbcUrl());
dataSource.setUsername(postgreSQLContainer.getUsername());
dataSource.setPassword(postgreSQLContainer.getPassword());
return dataSource;
}
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
HibernateJpaVendorAdapter vendorAdapter = new JpaVendorAdapter();
vendorAdapter.setDatabase(Database.POSTGRESQL);
vendorAdapter.setGenerateDdl(true);
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan("com.company.project");
factory.setDataSource(dataSource());
return factory;
}
#Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(entityManagerFactory);
return txManager;
}
}
}
EDIT: I believe this has something to do with the naming strategy?
For greater context here is an example of how the nativeQuery is used in the repository
#Repository
public interface NativeQueryRepository extends JpaRepository<NativeEvent, Long> {
#Modifying
#Transactional
#Query(value = "UPDATE native_event SET state = :state " +
"WHERE secondary_id = :secondaryId", nativeQuery = true)
void updateState(
#Param("state") String state,
#Param("secondaryId") String secondaryId);
}
I also tried update the testProperties on the static class inside TestPostgresql by adding the annotation:
#TestPropertySource(properties = {
"spring.jpa.hibernate.naming-strategy=org.springframework.boot.orm.jpa.SpringNamingStrategy"
})
However, with no change to the error received.
EDIT: add NativeEvent:
#Entity
#Table(
name = "NativeEvent",
indexes = {
#Index(name = "idx_native_event_secondary_id", columnList = "secondaryId")
}
)
#EntityListeners(AuditingEntityListener.class)
#Data
#Builder
#AllArgsConstructor
#NoArgsConstructor
public class NativeEvent implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name="secondaryId", nullable=false)
private String secondaryId;
#Column(name="state")
private String state;
}
You are doing manual configuration instead of using the runtime configuration. Hence different treatment of naming strategies. Instead you should be reusing the same configuration instead of writing your own.
Either use an #SpringBootTest or #DataJpaTest and only re-configure the DataSource.
Do something with an ApplicationContextInitializer to get the JDBC properties into the ApplicationContext.
#RunWith(SpringRunner.class)
#SpringBootTest
#ContextConfiguration(initializers = {TestPostgresql.JdbcInitializer.class})
public class TestPostgresql {
#ClassRule
public static PostgreSQLContainer postgreSQLContainer = PostgresDbContainer.getInstance();
/**
* ************ REPOSITORIES ************
*/
#Autowired
NativeQueryRepository nativeQueryRepository;
static class JdbcInitializer
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
TestPropertyValues.of(
"spring.datasource.url=" + postgreSQLContainer.getJdbcUrl(),
"spring.datasource.username=" + postgreSQLContainer.getUsername(),
"spring.datasource.password=" + postgreSQLContainer.getPassword()
).applyTo(configurableApplicationContext.getEnvironment());
}
}
}
This will reuse the configuration from the runtime in your test. Instead of #SpringBootTest you should als be able to use #DataJpaTest(NativeQueryRepository.class) to make a sliced test for JPA only.
You assign your table name explicitly like this:
#Table(name = "NativeEvent")
but in your native query you have a different name for that table:
#Query(value = "UPDATE native_event ...)
Either remove the name attribute from your #Table annotations (assuming your naming strategy will produce names like native_event) or change table name in native query to be nativeevent or nativeEvent so in this case just remove the underscore.
Somewhat related post
Related
I am using spring-boot-starter-jdbc and trying to use multiple Jdbc DataSources, everything worked when I used named Beans for my JdbcTemplate and then used #Qualifier to inject the right JdbcTemplate into my repository.
Application:
package my.app;
#SpringBootApplication
#EnableAutoConfiguration
public class Application implements CommandLineRunner {
#Autowired
private MyRepository repository;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Override
public void run(String... args) throws Exception {
List<Stuff> stuff = repository.getStuff();
}
}
Configuration:
package my.app;
#Configuration
#ComponentScan
public class AppConfig {
#Bean(name = "datasource1")
#ConfigurationProperties(prefix = "db1.datasource")
public DataSource dataSource1() {
return DataSourceBuilder.create().build();
}
#Bean(name = "db1")
public DataSource db1(#Qualifier("datasource1" DataSource ds) {
return new JdbcTemplate(ds);
}
#Bean(name = "datasource2")
#ConfigurationProperties(prefix = "db2.datasource")
public DataSource dataSource2() {
return DataSourceBuilder.create().build();
}
#Bean(name = "db2")
public DataSource db1(#Qualifier("datasource1" DataSource ds) {
return new JdbcTemplate(ds);
}
}
Repository:
package my.app;
#Repository
public class MyRepository {
private JdbcTemplate db1;
private JdbcTemplate db2;
#Autowired
public class MyRepository(#Qualifier("db1") JdbcTemplate db1, #Qualifier("db2") JdbcTemplate db2) {
this.db1 = db1;
this.db2 = db2;
}
}
When I instantiate MyRepository everything is fine.
I did a little refactoring to try to make new classes for Db1JdbcTemplate and Db2JdbcTemplate so I could inject them without qualifiers. Unfortunately when I do this I get the following exception:
Here's what I attempted to do:
Removed named JdbcTemplate Beans from AppConfig:
package my.app;
#Configuration
#ComponentScan
public class AppConfig {
#Bean(name = "datasource1")
#ConfigurationProperties(prefix = "db1.datasource")
public DataSource dataSource1() {
return DataSourceBuilder.create().build();
}
#Bean(name = "datasource2")
#ConfigurationProperties(prefix = "db2.datasource")
public DataSource dataSource2() {
return DataSourceBuilder.create().build();
}
}
Created 2 new classes for named JdbcTemplates:
package my.app;
#Component
public class Db1JdbcTemplate extends JdbcTemplate {
#Autowired
public Db1JdbcTemplate(#Qualifier("datasource1") DataSource ds1) {
super(ds1);
}
}
package my.app;
#Component
public class Db2JdbcTemplate extends JdbcTemplate {
#Autowired
public Db2JdbcTemplate(#Qualifier("datasource2") DataSource ds2) {
super(ds2);
}
}
Modified MyRepository to use those:
package my.app;
#Repository
public class MyRepository {
private Db1JdbcTemplate db1;
private Db2JdbcTemplate db2;
#Autowired
public class MyRepository(Db1JdbcTemplate db1, Db2JdbcTemplate db2) {
this.db1 = db1;
this.db2 = db2;
}
}
So I have #Component annotations on both of those so I expected to be able to be registered and be able to be Autowired. However when I run things I get the following exception:
Error creating bean with name 'repository' defined in file
[/Users/me/spring/target/classes/my/app/MyRepository.class]:
Unsatisfied dependency expressed through constructor parameter 0;
nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type 'my.app.Db1JdbcTemplate' available: expected
at least 1 bean which qualifies as autowire candidate. Dependency
annotations: {}
Any ideas what I need to change or how I can debug further? I can always go back to the working version but I'd prefer to be more explicit when possible so the compiler can help me out instead of runtime errors caused by a typo'd Qualifier name.
A more standard way of doing this and avoid typos in qualifier names is to avoid using qualifier names, and instead use Qualifier annotations:
#Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
#Retention(RetentionPolicy.RUNTIME)
#Documented
#Qualifier
public #interface DB1 {
}
#Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
#Retention(RetentionPolicy.RUNTIME)
#Documented
#Qualifier
public #interface DB2 {
}
and then, when defining your beans:
#Configuration
#ComponentScan
public class AppConfig {
#Bean
#ConfigurationProperties(prefix = "db1.datasource")
#DB1
public DataSource dataSource1() {
return DataSourceBuilder.create().build();
}
#Bean
#DB1
public JdbcTemplate db1(#DB1 DataSource ds) {
return new JdbcTemplate(ds);
}
#Bean
#ConfigurationProperties(prefix = "db2.datasource")
#DB2
public DataSource dataSource2() {
return DataSourceBuilder.create().build();
}
#Bean
#DB2
public JdbcTemplate db1(#DB2 DataSource ds) {
return new JdbcTemplate(ds);
}
}
And finally when injecting your beans:
public class MyRepository(#DB1 JdbcTemplate db1, #DB2 JdbcTemplate db2) {
...
}
If the main concern is typos, just define your names as constants (something like public static final String DATASOURCE1 = "datasource1";) and consistently use those in your qualifier annotations instead of string literals. No need to add new classes or interfaces.
I have a pretty simple spring-data-jpa + Hibernate application, which stores customers data in MySql Database (the full source code is posted here).
The problem is that it runs insert and select queries very slowly, comparing to what I have through mysql CLI:
insert one row takes ~3600ms,
select all (just 2 rows) takes ~1700ms
both queries take in mysql CLI about 0.12s.
There is a similar problem discussed here, however in my case the measurements are way worse (even though I don't insert batch, it's just one simple row in DB). Is there any way to improve performance in Spring JPA/Hibernate?
Another question, is there any way to reduce size of spring-data-jpa and hibernate-entitymanager? I was able to exclude byte-buddy and jandex dependencies without harm to the program, but that's only couple Mbs (the shaded jar size is down from 19.6Mb to 16.6Mb)?
UPDATE
As per request here is the code (the all sources are here):
#Entity
#AttributeAccessor("field")
#Table(name = "customer")
public class Customer implements Serializable{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="id",unique=true, nullable=false, insertable=true, updatable=true)
#Type(type="long")
private Long id;
#Column(name = "name")
private String name;
//+ constructors, getters/setters
}
Here is Spring application and also saving (insert) customer:
public class Application {
private static ApplicationContext applicationContext;
static CustomerRepository customerRepository;
public static void main(String[] args) throws InterruptedException {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MySQLAutoconfiguration.class);
customerRepository = ctx.getBean(CustomerRepository.class);
runTest();
}
private static void runTest () throws {
...
//insert
Customer customerJohn = customerRepository.save(new Customer("John"));
//select
Customer foundEntity = customerRepository.findOne(customerJohn.getId());
...
}
And configuration:
#Configuration
#ComponentScan
#EnableJpaRepositories (basePackages = "com.vk.dal.repository")
#PropertySource("classpath:mysql.properties")
public class MySQLAutoconfiguration {
#Autowired
private Environment env;
#Bean
public DataSource dataSource() {
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty("spring.datasource.driver-class-name"));
dataSource.setUrl(env.getProperty("spring.datasource.url"));
dataSource.setUsername(env.getProperty("spring.datasource.username") != null ? env.getProperty("spring.datasource.username") : "");
dataSource.setPassword(env.getProperty("spring.datasource.password") != null ? env.getProperty("spring.datasource.password") : "");
return dataSource;
}
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource);
em.setPackagesToScan("com.vk.dal.domain");
em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
Properties properties = additionalProperties();
if (properties != null) {
em.setJpaProperties(properties);
}
return em;
}
#Bean
JpaTransactionManager transactionManager(final EntityManagerFactory entityManagerFactory) {
final JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory);
return transactionManager;
}
final Properties additionalProperties() {
final Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("mysql-hibernate.hbm2ddl.auto"));
hibernateProperties.setProperty("hibernate.dialect", env.getProperty("mysql-hibernate.dialect"));
hibernateProperties.setProperty("hibernate.show_sql", env.getProperty("mysql-hibernate.show_sql") != null ? env.getProperty("mysql-hibernate.show_sql") : "false");
return hibernateProperties;
}
}
Appreciate any help.
My springboot app tries to read data from two datasources(emwbis and backupemwbis). I've followed the below link in configuring my springboot app to read data from two different datasources.
http://www.baeldung.com/spring-data-jpa-multiple-databases
The current problem with my app is it is always reading data from the primary datasource(emwbis). I've written below code.
Model classes for primary and backup datasources:
package com.jl.models.primary;
#Entity
#Table(name = "crsbis",schema="emwbis")
#Data
public class CrsBIS {
#Id
private String id;
#NotNull
private String email;
package com.jl.models.backup;
import lombok.Data;
#Entity
#Table(name = "crsbis",schema="backupemwbis")
#Data
public class CrsBIS {
#Id
private String id;
#NotNull
private String email;
Datasource config classes for primary and backup datasources:
#Configuration
#PropertySource("classpath:persistence-multiple-db.properties")
#EnableJpaRepositories(basePackages = "com.jl.dao.backup", entityManagerFactoryRef = "crsBISBackUpEntityManager", transactionManagerRef = "crsBISBackupTransactionManager")
public class BackupCrsBISDatabaseConfig {
#Configuration
#PropertySource("classpath:persistence-multiple-db.properties")
#EnableJpaRepositories(basePackages = "com.jl.dao.primary", entityManagerFactoryRef = "crsBISEntityManager", transactionManagerRef = "crsBISTransactionManager")
public class CrsBISDatabaseConfig {
Repository interfaces for primary and backup datasources:
#Transactional
public interface CrsBISRepository extends JpaRepository<CrsBIS, String> {
public CrsBIS findById(String id);
}
#Transactional
public interface CrBisBackupRepository extends JpaRepository<CrsBIS, String>{
public CrsBIS findById(String id);
}
Persistent db proeprties file :
jdbc.driverClassName=com.mysql.jdbc.Driver
crsbis.jdbc.url=jdbc:mysql://localhost:3306/emwbis
backupcrsbis.jdbc.url=jdbc:mysql://localhost:3306/backupemwbis
jdbc.user=root
jdbc.pass=Password1
Controller class to test both the datasources :
#Controller
public class CrsBISController {
#Autowired
private CrsBISRepository crsBISRepository;
#Autowired
private CrBisBackupRepository crsBackupRepository;
#RequestMapping("/get-by-id")
#ResponseBody
public String getById(String id){
String email="";
try{
CrsBIS crsBIS = crsBISRepository.findById(id);
email = String.valueOf(crsBIS.getEmail());
}catch (Exception e) {
e.printStackTrace();
return "id not found!";
}
return "The email is : "+email;
}
#RequestMapping("/get-by-id-backup")
#ResponseBody
public String getByIdFromBackup(String id){
String email="";
try{
com.jl.models.backup.CrsBIS crsBIS = crsBackupRepository.findById(id);
email = String.valueOf(crsBIS.getEmail());
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
return "id not found!";
}
return "The email is : "+email;
}
Although, I've separated the database schemas in the model classes and in the database config file, both the methods in the controller class hit the same database (emwbis). I want getByIdFromBackup method in controller class to read the data from secondary database (backupemwbis).
Can someone please let me know the mistake in my code? Or you can suggest/guide me to achieve my goal?
From the first configuration file you're creating a primary datasource bean definition with the name myDatasource and in the second emf you're injecting the same datasource reference.
The Bean causing the problem is this
#Bean
#Primary
public DataSource myDataSource()
Just change the second Bean datasource name and use it in the second EMF.
public class BackupCrsBISDatabaseConfig {
...
#Bean
public DataSource backupDS() {
....
#Bean
public LocalContainerEntityManagerFactoryBean crsBISBackUpEntityManager() {
....
em.setDataSource(backupDS());
}
}
Hope this fixes it.
You have to explicitly request a TransactionManager implementation in your #Transactional usage:
#Transactional("crsBISTransactionManager")
//..
#Transactional("crsBISBackupTransactionManager")
//..
I'm trying to save entity in repository but it does not work at all. Repository is Autowired and in runtime I use saveAndFlush to save entity. I'm using PostgreSQL. Above test methods I added comments with explanation what is going on. I expected that method saveAndFlush should work but it did not. I can not find why.
#Transactional
public class TestClass{
#Autowired private MyRepository repository;
#Autowired private EntityManager entityManager;
// Working version
public void writingToRepositoryWorking() {
entityManager.getTransaction().begin();
entityManager.persist(new MyData(99));
entityManager.getTransaction().commit();
}
// not working and throws exception :
// TransactionRequiredException: no transaction is in progress
public void writingToRepositoryNotWorking() {
repository.saveAndFlush(new MyData(99));
}
// not working, no exception, no data in repository,
// but auto generated ID is incremented
public void writingToRepositoryNotWorkingToo() {
repository.save(new MyData(99));
}
}
repository interface file
#Repository
#Transactional
public interface MyRepository extends JpaRepository<MyData, Long> {}
MyData file
#Entity(name = "myData")
public class MyData {
#Id #GeneratedValue(strategy = GenerationType.AUTO) long id;
private int testValue;
public MyData() { }
public BugData(int testValue) {
this.testValue = testValue;
}
public long getId() {
return id;
}
public int getTestValue() {
return testValue;
}
}
ApplicationConfiguration file
#Configuration
#EnableJpaRepositories("com.mypackage.app")
#EnableTransactionManagement
#PropertySource("classpath:application.properties")
#EnableWebMvc
class ApplicationConfiguration extends WebMvcConfigurationSupport {
#Value("${jdbc.url}") private String KEY_JDBC_URL;
#Value("${jdbc.username}") private String KEY_JDBC_USERNAME;
#Value("${jdbc.password}") private String KEY_JDBC_PASSWORD;
#Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
#Bean
#Autowired
public LocalSessionFactoryBean sessionFactory(DataSource dataSource) {
LocalSessionFactoryBean factory = new LocalSessionFactoryBean();
factory.setDataSource(dataSource);
factory.setPackagesToScan("com.mypackage.app");
factory.setHibernateProperties(hibernateProperties());
return factory;
}
public Properties hibernateProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
properties.setProperty("hibernate.show_sql", "true");
properties.setProperty("hibernate.hbm2ddl.auto", "update");
return properties;
}
#Bean
#Autowired
public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) {
return new HibernateTransactionManager(sessionFactory);
}
#Bean
public DataSource dataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName("org.postgresql.Driver");
dataSource.setUrl(KEY_JDBC_URL);
dataSource.setUsername(KEY_JDBC_USERNAME);
dataSource.setPassword(KEY_JDBC_PASSWORD);
return dataSource;
}
#Bean
public EntityManagerFactory entityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan("com.mypackage.app");
em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
em.setJpaProperties(hibernateProperties());
em.afterPropertiesSet();
return em.getObject();
}
#Bean
public EntityManager entityManager(EntityManagerFactory entityManagerFactory) {
return entityManagerFactory.createEntityManager();
}
...
}
For starter, you're actually working on 2 different EntityManager in your non-working test case:
EntityManager autowired into your test by Spring (this one is singleton and should be avoided anyway) ,other is
EntityManager created by the EntityManagerFactory configured in your ApplicationConfiguration.
At the same time, you also have another Session running along side the aforementioned 2 EntityManagers due to your configuration of Hibernate SessionFactory. Additionally, because of the configured HibernateTransactionManager, all transactions created by #Transactional are bound to the Hibernate's Session created by SessionFactory and the EntityManager used by your Repository certainly has no way to know about it. This is why TransactionRequiredException was thrown when your Repository tried to persist data.
To fix it, you may consider removing the Hibernate's SessionFactory and switch the transaction manager to a JpaTransactionManager. Then, #Transactional on your Repository will have the effect of creating a new transaction and binding it to the existing EntityManager that is known to Spring.
One side note is that the #Transactional on your TestClass doesn't help at all as the instance of this class is not instantiated and managed by Spring. To make this work, a proper configuration of transactional test class needs to be provided as described here: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/testing.html.
Hope this helps.
I have one global naming strategy but for a few entities I want to use a different one. Is it possible in jpa or hibernate?
clarification: i don't want to use #Table(name="xxx") nor #Column(name="xxx"). i'm asking about naming strategy component (described for example here: Hibernate naming strategy). that's a component that infer the column and table names for you
I don't see a way in the Hibernate source code. The EntityBinder is coming up with names using ObjectNameNormalizer.NamingStrategyHelper, which gets the naming strategy from either Configuration.namingStrategy (the global one) or from a complex path which goes through MetadataImpl and lands nowhere (no usages).
So you're likely stuck with overriding field names manually. I don't even see an obvious way to get context about the field, so I think even a split-brain naming strategy looks like it's out of the question.
Update: After seeing #anthony-accioly's answer, I thought I that last sentence may have been wrong. So I tested it as follows
package internal.sandbox.domain;
#Entity
public class SomeEntity {
private String id;
private String someField;
#Id
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getSomeField() {
return someField;
}
public void setSomeField(String someField) {
this.someField = someField;
}
}
with a JpaConfiguration as follows
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories("internal.sandbox.dao")
#Import(DataSourceConfiguration.class)
public class JpaConfiguration {
#Bean
#Autowired
public LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean(DataSource dataSource) {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setDatabasePlatform("org.hibernate.dialect.PostgreSQL82Dialect");
vendorAdapter.setDatabase(Database.POSTGRESQL);
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan("internal.sandbox"); // note, no ".domain"
factory.setDataSource(dataSource);
Properties properties = new Properties();
properties.setProperty("hibernate.cache.use_second_level_cache", "false");
properties.setProperty("hibernate.ejb.naming_strategy", "org.hibernate.cfg.ImprovedNamingStrategy");
factory.setJpaProperties(properties);
return factory;
}
...
a Spring Data DAO as follows
public interface SomeEntityDao extends CrudRepository<SomeEntity, String> {
}
and an integration test as follows
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = {ApplicationConfiguration.class, JpaConfiguration.class})
public class SomeEntityDaoIntegrationTests {
#Autowired
private SomeEntityDao someEntityDao;
#Test
public void testSave() {
SomeEntity someEntity = new SomeEntity();
someEntity.setId("foo");
someEntity.setSomeField("bar");
this.someEntityDao.save(someEntity);
}
}
I put breakpoints in the ImprovedNamingStrategy, and classToTableName() was called with "SomeEntity" and propertyToColumnName() was called with "someField".
In other words, package information isn't being passed in, so at least in this setup, it can't be used to apply a different naming strategy based on package name.