Spring Hibernate configuration for maven multi module - java

I have multi module project like below
DbUtils
Doctor Module Project
Patient Module Project
I have configured hibernate in DbUtils project with configuration file as below
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan(new String[] { "com.test.dbutils.pojos" });
Now I want to use this session factory in both sub modules and I want to setPackagesToScan Project wise.
i.e for Doctor Module com.test.doctor.pojos and for Patient module com.test.patient.pojos
Q.1) How to achieve this?
Q.2) Is there any other better approach creating and using session factory in multi modules?

If you are on Hibernate4+ then you may want to go thru http://docs.jboss.org/hibernate/orm/4.2/devguide/en-US/html/ch16.html
Otherwise, to my knowledge, you have to let JVM know about set packagesToScan at compile time. If you are running Doctor and Patient as separate SpringBoot applications or so[but still leveraging upon common code in DBUtils] then you have option to pass the packages as String via some application.properties file and set the right POJO package in the child module.
If you have both Doctor and Patient running in the same application, you can atleast try to pass multiple packages [sessionFactory.setPackagesToScan(new String[] { "com.test.doctor.pojos", "com.test.patient.pojos" });]

Related

How to set properties value in multi-module project?

I have a multi-module Spring Boot Gradle project. I have properties in each module yml file that point to database: user, pass, url.
It's working solution, but it's difficult to change project database. Every time I want switch database user or url, I must change 10+ yml files.
How to avoid this?
You could bind the properties in a class (see here: https://www.baeldung.com/configuration-properties-in-spring-boot) and inject the class where needed.

Hibernate schema generation consider entities from other maven modules

i'm using the Persitence class from javax for generating SQL scripts from our entities. And it works just fine, for the project where i'am currently in. Here is the code:
final Map<Object, Object> properties = new HashMap<>(dialect.getDefaultProperties());
properties.put(AvailableSettings.DIALECT, dialect.getClass().getName());
properties.put(AvailableSettings.CONNECTION_PROVIDER, DriverManagerConnectionProviderImpl.class.getName());
properties.put(AvailableSettings.DEFAULT_SCHEMA, schemaName);
properties.put(AvailableSettings.HBM2DDL_SCRIPTS_ACTION, "create");
properties.put(AvailableSettings.HBM2DDL_CREATE_SOURCE, "metadata");
properties.put(AvailableSettings.HBM2DDL_SCRIPTS_CREATE_TARGET, target.toURI().toURL().toString());
properties.put(AvailableSettings.USE_QUERY_CACHE, "false");
properties.put(AvailableSettings.USE_SECOND_LEVEL_CACHE, "false");
properties.put(AvailableSettings.IMPLICIT_NAMING_STRATEGY, "org.hibernate.boot.model.naming.ImplicitNamingStrategyComponentPathImpl");
properties.put(AvailableSettings.PHYSICAL_NAMING_STRATEGY, SpringPhysicalNamingStrategy.class.getName());
properties.put(AvailableSettings.JPA_VALIDATION_MODE, "ddl, callback");
properties.put(AvailableSettings.HBM2DDL_DATABASE_ACTION, "none");
properties.put(AvailableSettings.DRIVER, "org.h2.Driver");
properties.put(AvailableSettings.URL, "jdbc:h2:mem:export");
properties.put(AvailableSettings.HBM2DDL_DELIMITER, ";");
System.setProperty("line.separator", ";\n");
Persistence.generateSchema(schemaName, properties);
Generally it's working fine for the entities in the current project, but not fir external entites. I have a external maven module, which contains some entities i also need to be considered for our SQL script. Is there a way to define the external module in the properties, so the will be considered too ?
Create a maven module for your entities
Execute mvn clean install in this module
Add this module in the dependencies of the project that wants to use this modules' entities.
This is all you have to do and I also applied this in many projects.
Since you did not provide what you have done in this manner, cant't help more.
So, please try these steps and if there was a problem update your question with how to did the steps.
P.S: Also if this is the first time creating multi-module project, please google about multi-module maven project. There are plenty of useful posts out there.

Nested modules with Spring

I am developing project with Spring Framework.
I have created about 5 modules, sometimes one depend on other, but they are all on top level, and up to this point everything works fine.
Example:
Database module has only external dependencies
Identity module depends on database module
Facebook stuff module depends on identity module
Now, I have created directory in root of project called modules, and moved all modules into it (so they all were, and still are on same relative distance to each other).
All tests passes and I can build/compile and inspect classes without any problem.
However, now when I try to run only identity module (that does not require facebook stuff) spring throws me an exception, that it cannot find facebook beans. Of course it cannot, because there is no dependency, but I do not want to add this dependency. #Configuration is #Lazy so there is no point creating such #Bean anyway.
Code:
new AnnotationConfigApplicationContext(Application.class);
Application class is #Lazy #Configuration and does #ComponentScan from whole application, and as I understand it finds also #Configuration's from other modules and then - I do not know why - tried to create those #Bean's from other modules but fails as expected.
I have verified with git, that the only between working and not working states are moving those modules into new folder.
So to clarify, working/default structure is:
/.gradle
/.idea
/DatabaseModule
/IdentityModule
/FacebookModule
/.out
/.gitignore
and not working one is:
/.gradle
/.idea
/modules/DatabaseModule
/modules/IdentityModule
/modules/FacebookModule
/.out
/.gitignore
Code stays the same.
I think, that if I will add all dependencies to all modules then it will work but for obvious reasons I do not want to do this.
Am I doing something wrong?
Is there any convention, that I am breaking?
Bonus question: how are nested modules different, from ordinary folder containing modules?
EDIT:
I should also note, that all tests pass in both scenarios, however I am not using spring in tests (no dependency injection) - just new or Mock() everything

Spring dependency injection from webapp to external jars

I am integrating Java Plugin Framework within a Spring based web application (XML-free).
Everything is fine, except for the dependency injection in plugin context
For instance I have a data source I would like to use in a plugin without having to go back to property files by using #Autowired like for the rest of the application
I cannot find a way to do this except by using getBean, which I read was not the best practise on this subject.
I also had a look at LogicalDoc but this project resorts to properties reloading which is not the correct solution for me as I want beans attributes modifications to be available without further glue.
Does anyone know of an existing open source project where both these environment are used ?
Not being able to inject dependencies in plugins, I finally added the following methods to mother class of all plugins
public void setContext(ApplicationContextProvider a_ctx) {
m_theContext = a_ctx;
}
public ApplicationContext getApplicationContext() {
return m_theContext.getApplicationContext();
}
And retreive the beans from within the plugin by
getApplicationContext().getBean(*ClassType*)

WebSphere 8.5: unit testing & embeddable container

I'm trying to run the following unit test in a Maven project using a WebSphere 8.5 embeddable container:
import javax.ejb.embeddable.EJBContainer;
...
private EJBContainer ec;
#Before
public void setUp() {
final Map<String, Object> properties = new HashMap<String, Object>();
properties.put(EJBContainer.PROVIDER, "com.ibm.websphere.ejbcontainer.EmbeddableContainerProvider");
ec = EJBContainer.createEJBContainer(properties);
}
#Test
public void test1(){
...
}
But I'm getting the following exception in the setup method:
CNTR9403E: The embeddable enterprise bean container cannot start
multiple modules with the same file name: project1\target\classes and
project2\target\classes
Does anybody know how to get around this issue? I searched but couldn't find anything useful.
Edit:
I've found the documentation for the exception CNTR9403E here:
http://pic.dhe.ibm.com/infocenter/wasinfo/v8r5/index.jsp?topic=%2Fcom.ibm.websphere.messages.doc%2Fcom.ibm.ejs.container.container.html
CNTR9403E: The embeddable enterprise bean container cannot start
multiple modules with the same file name: {0} and {1}
Explanation User code has directed the embeddable container to start multiple modules with the same file name.
Action Specify a list of modules that does not have duplicate file names, or rename one of the modules with a unique file name.
But I don't see how I can fix this. Is it complaining about the two "classes" directories at the end of the paths? How can I solve this in a Maven multi-module project? Or is it a bug in WebSphere 8.5?
Yes, the classes directory name is causing the conflict. There is no workaround for using those directory names, so I would recommend testing the generated .jar instead, though I have no expertise with Maven, so I don't know how feasible that is. This is somewhat unsatisfactory, so you could open a WebSphere RFE to allow properties to be specified to disambiguate.

Categories