spring boot could show sql even use JdbcTemplate directly - spring-boot

spring boot project, used JdbcTemplate, and want to show sql which is executed, the configuration is as below
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
but nothing output, it seems above configuration only support spring data jpa, So I'd like to know does exist some manner could show sql even used JdbcTemplate directly?

There is a reason why the property is named spring.jpa something: it is to indicate you that it relates to JPA in some form.
If you're using JdbcTemplate, you're not using JPA hence that property can't have any effect. You can enable logging for the org.springframework.jdbc.core.JdbcTemplate class
logging.level.org.springframework.jdbc.core.JdbcTemplate=debug

Related

How to access datasource information in spring boot with spring data jpa and hibernate

I need to perform an health check on my application that uses spring boot with spring data jpa and hibernate.
I need to do this with jpa and not make specific to any implementation.
In EclipseLink we can use EntityManagerFactoryDelegate as shown below, but I dont know How to do this with spring data jpa and hibernate.
EntityManagerFactoryDelegate delegate = entityManager.getEntityManagerFactory().unwrap(EntityManagerFactoryDelegate.class);
PersistenceInfo = delegate.getSetupImpl().getPersistenceUnitInfo();
DataSourceImpl dataSource = (DataSource) info.getNpnJtaDataSource();
return dataSource.getName();
Can anyone suggest me how to do this in spring data jpa using hibernate.
You can use spring boot actuator dependency for healthcheck doesn't need to configure externally. Once you define Datasource Bean it will auto pick database healthcheck.
if you want to enable/disable database health check you can use the below property,
management.health.db.enabled=<boolean, true || false>
implementation reference :https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-features.html

Create javax.sql.DataSource and specify used schema

I'm currently working on implementing schema-based multi-tenancy for my Spring Boot / JdbcTemplate API application. I figured out that for it to work, in the DAO layer, I need to dynamically change the schema of the DataSource used by JDBCTemplate during the runtime, in other word create a new one, but I can't find any information on how to set properly the schema for the DataSource I'm creating.
EDIT
Here are some details that might be important : the schema is defined in the url of the API endpoints I created, as a mandatory variable: if the user calls the URL localhost:9090/schema/MyNewSchema/Test, the schema variable is MyNewSchema and I have to create a DataSource with the proper pointed schema MyNewSchema.
Found a possible answer if someone faces the same issue : https://springboot-vuejs-reactjs.blogspot.com/2019/08/springboot-multi-tenancy-with.html
I decided to use an AbstractDataSource class, as mentioned in the article, and to override the public DataSource dataSource() bean in the #SpringBootApplication class, with an injection of the AbstractDataSource class created earlier. This allows me to manipulate the DataSource used by JDBCTemplate dynamically during the application runtime.
Furthermore, in my AbstractDataSource class, the DataSource objects I manipulate are HikariDataSource, allowing me to define the schema I want the DataSource to point with a hikariDs.setConnectionInitSql("ALTER SESSION SET CURRENT_SCHEMA = MY_SCHEMA") statement (cf Configure OracleDataSource programmatically in Spring Boot with a default schema). In my case, I'm using Postgresql, so the SQL statement is SET SEARCH_PATH TO <schema-name>
It works pretty well !

Using #ConfigurationProperties in Spring Boot Application doesn't work

I am using Spring Boot V 1.4.1 for a new application.
My app requires two JDBC data sources and I was following the example at http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-two-datasources how to set it up.
My Spring beans configuration class is annotated with #EnableConfigurationProperties and my first bean is defined as
#Primary
#Bean
#ConfigurationProperties(prefix = "first.database")
DataSource qivsDB() {
return DataSourceBuilder.create().build();
}
, the second one accordingly. My application.properties file has properties defined like
first.database.url=jdbc:[redacted]
first.database.username=[redacted]
first.database.password=[redacted]
For reasons I not transparent to me during debugging this is failing to initialize: Cannot determine embedded database driver class for database type NONE - debug showed me that the builder does not have any properties set when calling build().
What did I miss here?
Before you do all the debugging part, you should have a look to the auto-configuration report. If you define your own DataSource there's no reason for Spring Boot to start looking at what it can do for your app. So, for some reasons, that definition of yours is not applied in your app and the default in Spring Boot still applies, doesn't find any JDBC url in the default namespace and attempt to start an embedded database. You should see in the auto-config report that the DataSourceAutoConfiguration still matches.
I am not sure the public keyword has anything to do with it, though you won't get custom meta-data for that key since we only scan for public methods.

How do I change my configuration to a different data source?

I went through the Data Access With Spring tutorial and the in memory database they use in step 3 is working. But, I'm not clear on what I need to add/change to get it to query my development (Oracle) database now?
I want to use Hibernate, do I still need this JPAConfiguration class or would I have something Hibernate specific?
Please don't just post a link to the Hibernate reference. I'm reviewing that as well, but since I'm also using Spring, it's not clear to me the proper way to load the hibernate.cfg.xml and inject the Hibernate session in that context.
Don't be blocked by the fact that the class is called JPAConfiguration. You need to understand what the class does. Note that it has the annotation #Configuration which you can use along with AnnotationConfigApplicationContext to produce a Spring bean context.
That functionality is described in the Spring documentation for The IoC container.
What you need to change is how your DataSource and EntityManagerFactory beans are created. You'll need to use a DataSource that gets Connection instances from a JDBC Driver that supports Oracle databases.

How to enable load time / runtime weaving with Hibernate JPA and Spring Framework

I'm using Hibernate as a JPA provider (I'm using its EntityManagerFactory instead of its SessionFactory) in a Spring Framework application. I managed to get Spring Framework's load time weaving support working, so I'm past that hurdle.
I need to enable lazy loading of byte[] and #ManyToOne properties on an entity. I understand how to instrument (weave) my entities at build time using Hibernate's ant task, but I'd like to instrument my entities at runtime instead (load time weaving). I've seen references to in on several Google search results, but no actual instructions for enabling it. What property do I need to set to instruct Hibernate that it can instrument my entities at runtime?
After considerable reading of code and debugging, I figured this out. It's a shame the Hibernate ORM documentation doesn't include this information. (To be fair, the Hibernate EntityManager documentation does, but it's not easily found. The Hibernate instructions on "Using lazy property fetching" only says, "Lazy property loading requires buildtime bytecode instrumentation." It does not mention that you can use runtime instrumentation with a Hibernate EntityManager property.)
The first thing you must do is set the "hibernate.ejb.use_class_enhancer" JPA property to "true" (String). This tells Hibernate that it may use the "application server" class transformation by calling addTransformer on the PersistenceUnitInfo instance. The "application server" class transformation is really Spring's LoadTimeWeaver. If you are using Spring's Java configuration and LocalContainerEntityManagerFactoryBean, and Hibernate is a compile-time dependency, you could use the AvailableSettings.USE_CLASS_ENHANCER constant instead of the string-literal "hibernate.ejb.use_class_enhancer" (which would make it typo-resistant).
If you are using Spring's Java configuration, there is an additional step you must take until SPR-10856 is fixed. LocalContainerEntityManagerFactoryBean's setLoadTimeWeaver method is not called automatically like it should be, so you must call it manually. In your #Configuration class, just #Inject or #Autowire a LoadTimeWeaver instance and call setLoadTimeWeaver manually when you are creating the LocalContainerEntityManagerFactoryBean.
With these steps taken, I'm now using Hibernate's runtime entity bytecode instrumentation with Spring Framework in Tomcat.
I have the similar problem. I followed the steps you have mentioned to setup the weaver successfully. I created run time entity using byte buddy with annotations. And loading this class at runt time. Created instance of the same using reflection and trying to persist. But hibernate complains as,
java.lang.IllegalArgumentException: Unknown entity:
I believe the run time entity which I created is not enhanced and hibernate is complaining the same.

Resources