I built my project using the Eclipse IDE, and placed my hibernate.cfg.xml file in the resources folder (screenshot below):
The problem occurs when I try to reference hibernate.cfg.xml in my DAO classes. Here is a snippet of my code where I get my SessionFactory:
DAO getSessionFactory() example
private static SessionFactory getSessionFactory() {
String hibernatePropsFilePath = "src/main/resources/hibernate.cfg.xml";
File hibernatePropsFile = new File(hibernatePropsFilePath);
Configuration configuration = new Configuration();
configuration.configure(hibernatePropsFile);
configuration.addAnnotatedClass(MyClass.class);
StandardServiceRegistryBuilder serviceRegistryBuilder = new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties());
ServiceRegistry serviceRegistry = serviceRegistryBuilder.build();
return configuration.buildSessionFactory(serviceRegistry);
}
As you can see, I'm still pointing to the "correct" location in my project, however when I test using Postman, I get the following error:
HTTP Status 500 - Request processing failed; nested exception is
org.hibernate.internal.util.config.ConfigurationException: Specified
cfg.xml file
[C:\Users\MYUSERNAME\Desktop\src\main\resources\hibernate.cfg.xml] does
not exist
My question: Why is it constantly looking in my Desktop for my file path, and how do I change it to look only in my project? I checked and made sure that my resources path is present in my Web Deployment Assembly (screenshot below):
src/main is maven specific project structure to arrange the source files. But after build the compiled classes and resource files are copied to WEB-INF/classes/ directory.
Assuming you are using maven and your resources folder is part of the source structure, then the XML file will be copied to WEB-INF/classes/resources folder.
Change the path to String hibernatePropsFilePath = "/resources/hibernate.cfg.xml";
Update:
After taking a second look at your Web Deployment Assembly settings image, your main/resources folder is mapped to classes directory not classes/resources. so change the code as shown below without use of File.
Configuration configuration = new Configuration("hibernate.cfg.xml");
configuration.addAnnotatedClass(ClientCrossRef.class);`
configuration.configure();
and even more better thing is, since your cfg.xml file is already part of classpath, you don't even need to specify it. Hibernate will look for it in the classpath.
And by the way, you can build the session factory easily as
SessionFactory sessionFactory = new Configuration().configure(
"hibernate.cfg.xml")
.buildSessionFactory();
Related
I am trying to externalize my ignite configuration in my spring boot application so the configuration can be changed without rebuilding the jar.
Previously the file resided in src/main/resrouces and was loaded via annotations.
#ImportResource("IgniteConfig.xml") and
#Autowired
private IgniteConfiguration cfg;
When I moved the IgniteConfig.xml to the config folder that resides next to the excutable jar the above stopped working and I have tried the following without success:
use --spring.config.location argument. I can tell this is picked up during run time as other configurations work but the above ImportResource annotation says the file IgniteConfig.xml cannot be found.
use a relative path to (e.g. ./config.IgniteConfig.xml) to Ignition.start. I cause this relative path to print the file contents of the xml file in my logs but when I pass it to Ignition.start it says the file cannot be found. I have tried using relative and absolute paths to do this.
Manually create an ApplicationContext and get the configuration by bean name.
ApplicationContext context = new ClassPathXmlApplicationContext("./config/IgniteConfig.xml");
This again complains that the file does not exist even though I can see by opening the file directly:
File igniteConfigFile = new File("./config/IgniteConfig.xml");
The comment by konqi in this post answered my question:
"In case you want to import a resource that is outside the classpath the syntax would be:
#ImportResource( { "file:path/spring-context1.xml", "file:path/spring-context2.xml" } )
"
In my case I just needed to do:
#ImportResource( { "file:./config/IgniteConfig.xml" } )
We have a web application on JBoss 7.2.
Now I want to display the build timestamp in my UI for debugging purposes, so I added
a properties file looking like that:
version=${pom.version}
build.date=${timestamp}
in the POM properties:
<properties>
<timestamp>${maven.build.timestamp}</timestamp>
<maven.build.timestamp.format>yyyy-MM-dd HH:mm</maven.build.timestamp.format>
</properties>
On build, this successfully generates a .properties file with the correct values, e.g.
version=0.1-SNAPSHOT
build.date=2021-08-25 12:00
However, when deployed, that properties file isn't available anymore. I get a FileNotFoundException when my frontend bean tries to access the file via
String propertyPath = "src/main/resources/version.properties";
try (InputStream properties = new FileInputStream(propertyPath)) {
Properties prop = new Properties();
prop.load(properties);
}
...
Now of course I can add the properties to my standalone.xml, but I wasn't able to replace the values during build time. Any tips on how to make it work?
The problem you are experiencing makes total sense. You are attempting to read the file using the source code path src/main/resources/version.properties. Since you have built your app and created a jar out of it, the file in question no longer resides under this path.
You should therefore attempt to load the file using the classloader. Check more on that here.
I have a pretty simple servlet setup with
Jersey
no web.xml
Tomcat 9
Maven for creating the .war and handling dependencies
Now I need to deploy a test and a production version of the servlet on the server and I a trying to use the individual context.xml file for each environment. A quote from the docs
Individual Context elements may be explicitly defined:
In individual files (with a ".xml" extension) in the $CATALINA_BASE/conf/[enginename]/[hostname]/ directory. The context path and version will be derived from the base name of the file (the file name less the .xml extension). This file will always take precedence over any context.xml file packaged in the web application's META-INF directory.
All this also sounds easy here:
To give an example: if we wanted to deploy three installations of an application for test, stage and production, we would create three context.xml files:
tomcat/conf/catalina/localhost/test.xml
tomcat/conf/catalina/localhost/stage.xmltomcat/conf/catalina/localhost/prod.xml
And then deploy the same .war file three times as:
tomcat/webapps/test.war
tomcat/webapps/stage.war
tomcat/webapps/prod.war
And each installation would pick up its specific configuration automatically.
You can also read this documentation:
For Tomcat 5.0.x and later, WTP 2.0.x and later offers the opportunity to write the contexts to separate XML files in the proper folder (typically conf/Catalina/localhost) according to the requirements of that particular version. This behavior is enabled by checking the Publish module contexts to separate XML files option in the Server Options section of the Tomcat server editor. Note that only contexts for added projects will be written to separate XML files. Manually added contexts in server.xml will remain there.
There are several instructions, how to retrieve a value from the context.xml. For example:
<Environment name="companyName" value="My Company, Incorporated" type="java.lang.String" />
Can be used by
InitialContext context = new InitialContext();
Context xmlNode = (Context) context.lookup("java:comp/env");
String companyName = (String) xmlNode.lookup("companyName");
But this was listed for a Spring setup, how can this be done in a Jersey ResourceConfig based application/servlet?
For example:
#ApplicationPath("/")
public class MyMain extends ResourceConfig {
private final Logger logger = LoggerFactory.getLogger(MyMain.class);
public MyMain() {
try {
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
String myEnv = (String) envCtx.lookup("my-env");
this.logger.debug("Env: {}", myEnv);
} ...
is running into NamedExceptions: javax.naming.NameNotFoundException: Name [my-env] is not bound in this Context. Unable to find [my-env].
Is there any way to get the context configuration with Jersey, or do I need to use a different approach?
I also have no clue, how to debug the InitialContext. So the file is there and it is read by Tomcat, but I don't know how I can access it in the application. Do I need to use ServletContext.getInitParameter() instead - and how?
Update
My Eclipse setup seems to be the problem, because the published xml file is not the original, individual context.xml in my /Catalina/localhost folder. Is there any way to make sure that the original file is published in the Eclipse-Tomcat server?
"Publish module contexts to separate XML files" is checked. What is Update context paths? in publishing options (no effect visible, though)?
Here is the :
I've tried to indicate a relative path to hibernate get the hibernate.cfg.xml but it does not work, because I've wrote that wrong (i've typed cgf instead of cfg in the file's name). So I've tried an absolute path but Hibernate doesn't recognize the new path, and still looking at the relative path that I've passed before. But the parameter .configure() has chenged, why does Hibernate ignore and insists in mistake?
My code:
private static SessionFactory buildSessionFactory() {
Configuration configuration = new Configuration();
// Use the mappings and properties specified in an application resource named hibernate.cfg.xml.
configuration.configure("C:\\Users\\Lucas_Pletsch\\eclipse-workspace\\PDV\\main\\resources\\hibernate.cfg.xml");
The error screen showing that Hibernate searched for hibernate.cfg.xml in the path that I've passed as parameter before:
Now I've tried this:
SessionFactory sessionFactory = new Configuration().configure("hibernate.cfg.xml").buildSessionFactory();
And the error message have changed, but Hibernate still not finding .cfg.xml:
Try updating your maven project: RightClick > Maven > Update Project.
If issue still persists place hibernate.cfg.xml file under the src folder.
Your hibernate.cfg.xml file is already part of classpath. you don't need to specify complete path
Try below code :
SessionFactory sessionFactory = new Configuration().configure(
"hibernate.cfg.xml")
.buildSessionFactory();
Update your project as: Right click on the project->select Maven->then select Update project
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.