-
Notifications
You must be signed in to change notification settings - Fork 40.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
EntityManagerFactoryBuilder does not apply spring.jpa.hibernate customizations automatically #3654
Comments
Thanks for the sample! Well you are creating the (and maybe fix a bug or two along the way 😄 ) |
Curiously all the other attributes are set automagically via the builders. This is true for both the DataSource and the EntityManagerFactory. Plus, the value in question is available via the autowired JpaProperties (which is automatically created by the spring-boot packages). So, I think this is a bug (or missing feature if you prefer). There is a need to slap an @primary on one of the DataSource instances or else spring complains. But otherwise, and except for the naming_strategy, everything gets wired up from the config/properties file with zero intervention. I'm of the opinion that naming_strategy should be included in that default auto-wiring. |
Compare our LocalContainerEntityManagerFactoryBean and yours. I haven't looked deeper than that but it's fairly different IMO. It's not a terminology problem (I don't have a problem calling something a bug when there is one). I just think your configuration is different. Maybe we can also fix that via a template method. I'll have a look. |
Hi Stéphane, So, this becomes a usage question on my end. How do I configure things so that the HibernateJpaAutoConfiguration is configured and used in the BarConfig class ? In particular, what's the recommended way to get or setup the EntityManagerFactory so that it is configured with all the vendor-specific settings (Hibernate in this case)? (I see how to do so for the primary data source. What's unclear is how to leverage that code for a secondary or tertiary data source. In my particular case I go a semi-custom route, but then I'm not using JTA, not using WebSphere, and not using an alternate vendor/provider. In short, would be nice if eithe some of the protected methods were public, or if the configuration methods took a datasource so that the subsequent layers could be configured using all the logic embedded in the existing Spring code.) Thank you. |
Hi @eepstein, no worries! I am not sure yet. I'll have a look tomorrow morning. Cheers! |
Perhaps XML config is the way to go in this case? |
What leads you to such conclusion? I haven't looked at it yet (last minute M3 stuff kept me busy) |
Okay so I have a good overview of the problem now. I have created a sample that exposes several steps. You can browse the initial version that is similar to what you end up doing. Like I said, you are creating the entity manager yourself so any customization that is done in the auto-configuration is lost (since you are overriding it). One of these customizations is to auto-detect the I am not sure I understand why we don't apply these in the builder since we have everything that we need. I'll probably change that. You can workaround the issue by specifying the following in your configuration
Now, what I find a bit disturbing about this setup is that the JPA settings are shared between the two persistence units. What if you want different settings? To demonstrate this, I have completely disabled the auto-configuration and created a two sets of Finally, that project also showcases how you can generate the relevant meta-data for those new keys so that you get content assistance in the IDE. I hope that helps. TL;DR the builder should apply the customization internally, I see no reason why it doesn't do it but keep in mind that since you are overriding things, it is normal that you lose some of the auto-magic features. |
While the EntityManagerFactoryBuilder holds the JpaProperties object, it does not apply the Hibernate-specific customizations. Currently, the auto-configuration pass an extra `properties` map that is created by default based on these customizations. Unfortunately, we cannot change that as the JTA auto-configuration is relying on the content of the vendor properties. To mitigate the problem, EntityManagerFactoryBuilder applies the Hibernate customizations if no specific properties have been set. Closes spring-projectsgh-3654
Hi Stéphane, So some of that lines up with my own observations and conclusions and some is either new or didn't line up with my own explorations and I'm not sure what I should have done instead. So, in no particular order:
Should I look for an enhanced builder or some template method in a subsequent release? |
Something should be wrong in your project then since I got it working. That demonstrates
We're still discussing my PR at this point. |
I'd tried spring.jpa.hibernate.naming_strategy That's the one that works with a single DS/EM. Didn't try the one with .properties. in the path/name. Sent from my handheld, please excuse typos.
|
The key is |
I think you misunderstood my point. Yes, the standard property does not work (that's why this issue exists). I am proposing a workaround for the time being.
|
@wilkinsona if we want to refactor the JPA auto-configuration to be independent of Hibernate somehow, maybe we should take into account the Hibernate 4/5 support as certains keys need to be handled differently according to the hibernate version. See snicoll@161c629 From what I can see, |
Finally!! Relevant reading: https://medium.com/@joeclever/using-multiple-datasources-with-spring-boot-and-spring-data-6430b00c02e7 https://scattercode.co.uk/2016/01/05/multiple-databases-with-spring-boot-and-spring-data-jpa/ Application settings is not implicitely added to new data source: spring-projects/spring-boot#3654
@snicoll Although it was indeed possible for me to configure custom naming strategy for hibernate following your examples I cannot figure out how to provide a custom naming strategy which needs to be created by spring (because of some dependencies). Could you point me somehow the right direction? Before going with multi datasource it was as simple as defining a bean:
But it no longer works. |
If anybody ever run into similar problem, here is how I solved it:
|
Hi - I appreciate this is an old issue which is probably quite niche. However, I've recently encountered it and it was difficult to debug because I wasn't aware that Spring was applying this naming strategy for me, so the mapping errors I was getting were quite confusing. Lesson learned on that count. For my use case, it would be ideal if the I understand why this may not be possible or desirable, but in any case may I ask that you consider updating the relevant section of the documentation to make it clear that the properties must be explicitly passed in to the builder? This would have saved me a fair amount of time! Thank you. |
@petenattress Could you please open a new issue to capture your suggestions? We can then use it to decide if we should update the docs or make a change to how |
When using a single data source and entity manager in a Spring Boot JPA project, the hibernate settings are picked up from the application properties (e.g., the application.yml file) and applied as expected.
In the case of multiple data source and entity managers, the naming_strategy setting is not applied and thus we get the default naming strategy. A minor bug with a likely quick fix I imagine.
I've put together a sample project showing the issue:
https://github.com/eepstein/multids-demo
(which was forked from https://github.com/gratiartis/multids-demo)
The relevant lines are in the FooConfig and BarConfig classes. For example, from com.sctrcd.multidsdemo.integration.config.foo.FooConfig:
If you comment out that line you'll see an assertion in the test will fail, even though the naming strategy is being correctly set in the application-test.yml file in the test resources folder.
The text was updated successfully, but these errors were encountered: