hibernate entity discovery only works inside the same folder - java

I have a Spring Boot project with Hibernate.
The project does not have a hibernate.cfg.xml file.
The project also does not have an applicationContext.xml file.
Nevertheless, all works well.
However, when I start adding new hibernate entities, then things go wrong. For some reason, the system only finds them when I put them inside the package of the other hibernate entities.
So, this leads me to believe that I do need additional configuration to help the auto-discovery mechanism. But what is the state-of-art in 2020 ? (I assume that the above xml files are now deprecated).

If you use spring + hibernate then it solved by #ComponenScan annotation.
If pure hibernate then I think you need persistence.xml
EntityManager is the class that performs database interactions in JPA.
It is initialized through a configuration file named persistence.xml.
This file is found in the META-INF folder in your CLASSPATH, which is
typically packaged in your JAR or WAR file. The persistence.xml file
contains:
The named "persistence unit," which specifies the persistence framework you're using, such as Hibernate or EclipseLink.
A collection of properties specifying how to connect to your database, as well as any customizations in the persistence
framework
A list of entity classes in your project

I totally overlooked these annotations which were present on the SpringBootApplication class.
#SpringBootApplication(scanBasePackages = {"com.domain.foo.bar.*"})
#EnableJpaRepositories(basePackages ={"com.domain.foo.bar.*"})
#EntityScan(basePackages ={"com.domain.foo.bar.*"})
public class SpringBootApplication extends SpringBootServletInitializer {
}
I needed to add my packages here.

Related

Grails not mapping entities from hibernate.cfg.xml file

I am trying to create a sample project to demonstrate the use of grails 5 with gorm 7.
Here I am trying to map hibernate entities using hibernate.cfg.xml file. The hibernate.cfg.xml file is placed under grails-app/conf/ diectory.
The hibernate entity java classes are annotated with javax.persistence.Entity annotation.
But these entity classes are not mapped by grails and performing any save, list etc operations on these entities throws org.hibernate.MappingException: Unknown entity exception.
Please find the sample project here.
Can you try moving the hibernate.cfg file to hibernate folder or refer the path in application.yml https://docs.grails.org/3.0.x/guide/hibernate.html

How to get Hibernate to scan for Entities in a jar file included in the jar

I have a vexing problem.
I'm upgrading stuff to j11 and the latest of everything but I can't change too much of the app itself. The created jar file contains within itself a jar file that contains mapped entities, like this:
jar
BOOT-INF
classes
application classes
lib
entity lib
META-INF
persistence.xml
In my persistence.xml I refer to the entity lib through the <jar-file> directive like so:
<jar-file>BOOT-INF/lib/EntityLib-1.0.jar</jar-file>
But the scanner can't find it. (I get java.nio.file.NoSuchFileException: BOOT-INF/lib/EntityLib-1.0.jar)
I've read parts of JSR-338, JPA 2.1 and looked at the examples but I haven't gotten any further.
I'm using Hibernate 5.3.3.Final
This is a spring boot application but the original developers used basic JPA instead of the spring func and I'm not allowed to rewrite the app that much (nor do I want to, to be honest).
EDIT: the app is created through the normal spring-boot-maven-plugin.

Spring-boot > implicitly auto register a 3rd party bean

This may be an impossible task, but here goes...
Is it possible to register a spring bean, by (ONLY) adding a jar to the classpath of a spring-boot application?
Scenario: I would like to create a non-intrusive plugin jar, which when imported into a spring-boot project's classpath, will automatically be picked up and provide a service (e.g. via a RestController).
Constraints
I don't want to change or reconfigure the existing spring-boot application (i.e. no additional scan paths or bean config).
I don't have any knowledge of the target spring-boot application's package structure/scan paths.
I guess I was hoping that by default Spring scan's its own package structure (i.e. org.springframework.** looking for the presence of database libs, etc) and I could piggy-back off that - I haven't had any luck (so far).
I've setup an example project in github, to further clarify/illustrate my example and attempts.
** Solution Addendum **
This bit that got it working, was to add the following file, which points to an #Configuration config file...
plugin-poc\src\main\resources\META-INF\spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.thirdpartyplugin.PluginConfiguration
I think in such cases you would try to add a spring auto configuration that is annotated with #ConditionalOnClass to be only evaluated if the given class is on the classpath. This class can register the bean and would just be evaluated if the conditional evaluates to true
Here is the relevant part of the spring boot documentation : Creating your own auto-configuration

Why the mapping.xml and configuration.xml has to be outside the pojo package?

I have just started to learn the Hibernate and found this in various online sites : mapping.xml and config.xml has to be defined outside the pojo package?
Why is that so?
Also what's the difference between JPA and Hibernate. I searched through web and According to me hibernate is just one of the implementation of JPA. Could u correct me.
I have just started to learn the Hibernate and found this in various online sites : mapping.xml and config.xml has to be defined outside the pojo package?
You can put xml configurations whenever you want. For an example
SessionFactory factory = new Configuration().configure().buildsessionFactory();
Configure a session factory from the default hibernate.cfg.xml. It is the same as
SessionFactory factory = new Configuration()
.configure("hibernate.cfg.xml").buildsessionFactory();
So why hibernate.cfg.xml should be in the root of the source folder (or in the resources folder) in this situation?
Hibernate tries to load hibernate.cfg.xml via class loader
InputStream stream = classLoader.getResourceAsStream( "hibernate.cfg.xml" );
if you specify just a name without a path ("hibernate.cfg.xml") a class loader will try to find a resource in the root of the compiled sources folder — bin or build folder, or the classes folder for war. The resources folder after build is copied (for an example, by Maven) in the root of the build or classes folder.
if you specify
new Configuration()
.configure("/some/pojo/hibernate.cfg.xml").buildsessionFactory();
A class loader will try to find a resource in the some.pojo package. In this situation Hibernate removes the leading /, because of for a loading via a class loader the leading / is incorrect. So you can use a code below too
new Configuration()
.configure("some/pojo/hibernate.cfg.xml").buildsessionFactory();
The same rule for other paths to the xml resources.
Also what's the difference between JPA and Hibernate. I searched through web and According to me hibernate is just one of the implementation of JPA. Could u correct me.
Yes, Hibernate is an implementation of JPA. But one thing more. If you use the SessionFactory you can think that you don't use JPA. But in the same time you use JPA annotations (#OneToMany for an example). When you use EntityManager — you use JPA exactly.

Adding jpa/hibernate #Entity in submodule in playframework to entity manager to scan

I have problem with hibernate entity while working with submodules in playframework.
Normally (in single app without submodules) I've used that code:
package models;
#Entity
public class AppMode {
public static AppMode getCurrentConfigurationEntry() {
return JPA.em().find(AppMode.class, 1L);
}
}
But now I have to tell hibernate entity manager to scan submodules models, cause I'm getting an error:
[IllegalArgumentException: Unknown entity: AppMode]
My model class in submodule is in package:
package models.common;
I've already tried:
return JPA.em().find(models.common.AppMode.class, 1L);
return JPA.em().find(common.models.AppMode.class, 1L);
but I'm getting the same error:
[IllegalArgumentException: Unknown entity: models.common.AppMode]
My question is: How to configure hibernate in play subproject to add submodules models class to classpath at runtime?
I have in both build.sbt files declared libraryDependencies with hibernate.
Should I have persistence.xml file/configuration for each module?
I have to mannually add mapping thought xml persistance file and also using Annotation Mapping: #Entity
I think that your problem is about JPA configuration. Check this this answer which explains JPA multi-module configuration.
Good luck!
I think Hibernate only scans for JPA Entities inside jar files, and not in classes/ folders for example, or it only scans in the jar with the persistence.xml, or something like that. Here's a solution with pure Hibernate on JavaSE, no Spring: https://stackoverflow.com/a/41845759/377320

Categories