I am working on EJB3. Is it possibe to create Oracle DB table at run time through Entity Bean?
For this i have created a entity bean and i have made entry for this bean to persistence.xml also. I thought it will create DB table at run time. But table was not created.
Is it possible to create table at run time through entity bean. If yes what i am doing wrong.
Thankx in advance for your time and help
You can configure entity generation in your persistence.xml, sample is shown below.
Make changes according to your environment.
<property name="toplink.ddl-generation"
value="drop-and-create-tables"/>
<!-- Generating derby specific sql -->
<property name="toplink.platform.class.name"
value="oracle.toplink.essentials.platform.database.DerbyPlatform"/>
Also if you are using EJB-3.x, no need to make entry of entity beans in persistence.xml, use annotations instead.
Related
This is very strange.
I am using the spring.jpa.generate-ddl=true to create the tables in my database. When spring does this, the table names are snake case.
For example, the table for MyClass becomes my_class.
Next, I exported the schema from Hibernate using this code:
Export schema from Hibernate
When I call the code, the resulting sql has table names in camel case with the first letter capitalized. So, the table for MyClass is MyClass.
Why would they generate differently?
How do I get them to be the same?
The table names are different because Spring configures Hibernate to use a different naming strategy. The naming strategy defines how Hibernate generates the logical name of an attribute or entity and how to map them to the physical name in the database. I explain that in more detail in the Naming Strategy Guide on my blog.
You have multiple options to ensure both of your setups use the same naming strategy:
If you're using a Hibernate version >= 5.5.4, you can configure it to use the CamelCaseToUnderscoresNamingStrategy. That's the one that Spring is using by default:
<persistence>
<persistence-unit name="my-persistence-unit">
...
<properties>
...
<property name="hibernate.physical_naming_strategy"
value="org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy"/>
</properties>
</persistence-unit>
</persistence>
If you're using an older Hibernate version, you might want to change Spring's naming strategy to Hibernate's default strategy. You can do that by setting the following property in your application.properties file:
spring.jpa.properties.hibernate.implicit_naming_strategy=default
If you're using an older Hibernate version and want to use Spring's naming strategy, you have to implement a custom naming strategy. This isn't complex, and I explain how to do it in my blog post, but I would choose one of the previously mentioned solutions.
I was working on a Spring-data-jpa project with spring boot, I see that the creation of repository beans required a datasoure bean to be present, Why is it so?
And can a repository bean be created without datasource bean.
The purpose of a repository is to load and save data into a persistent store.
Spring Data JPA does that using JPA so it needs an EntityManager which in turn need a DataSource.
Strictly speaking the DataSource is only used once the database is actually accessed.
While you definitely nee a DataSource bean you may delay the construction of a normal DataSource by providing a wrapper which instantiates the the actual DataSource at a later point in time.
DelegatingDataSource might be of help, either as a basis class or, since you are going to change the DataSource as a template for an implementation.
See the somewhat related question https://stackoverflow.com/a/61208585/66686
I want to clarify my problem a bit more:
I understand the purposes of using SPring Framework (i.e. container-managed object lifecycle) and also Hibernate (using ORM between Javaobjects and relational database systems - impedance mismatch resolution).
I understand how we autowire an object and Spring takes over the creation and destruction of the object during runtime by looking at the applicationContext.xml file (in addition to persistence.xml file if using Hibernate or any other persistence provider).
What I want to do is the following:
I would like to implement my own shopping service. I already have entity (item) annotated with #Table, #Id, #Column, etc. to tell JPA that this is what will be stored in the database.
I already have a DAO interface (currently only add and delete methods) implemented by a DaoImpl class where I have done the following:
#Repository
#Transactional
public class MyShopDbDaoImpl implements MyShopDbDao {
// The following named unit will be in my persistence.xml file
// Which will be placed in src/main/resources/META-INF folder
#PersistenceContext(unitName="myShopDbDao")
private EntityManager em;
// Getters for em (simply returns em)
// Setters for em (simply assigns an em supplied in the args.)
// Other query method
}
I also have a ShopDbController controller class that uses:
#Autowired
// defined in the applicationContext.xml file
private MyShopDbDao myShopDbDaoImpl
What I am struggling with is the "Understanding" of EntityManagerFactory and EntityManager relationships along with how the transactions must be managed. I know that the following hierarchy is the main starting point to understand this:
Client talks to a controller.
Controller maps the request and gets the entitymanager to do queries and stuff to the database (either a test/local database with JUNIT test etc. or an actual SQL-type database).
What I do know is that transactions can be managed either manually (i.e. beginning, committing, and closing a session) or through Spring container (i.e. using bean defs in applicationContext.xml file). How can I get more information about the entitymanagers and entitymanagerfactory in order to setup my system?
I didn't find the online documentation from Oracle/Spring/Hibernate very helpful. I need an example and the explanation on the relationship between entitymanagerfactory, sessionfactory, entitymanager, and transactionmanager. Could someone please help me with this?
I don't need people to hold my hand, but just put me in a right direction. I have done Spring projects before, but never got to the bottom of some stuff. Any help is appreciated.
EntityManagerFactory will obtain java.sql.Connection objects, through opening/closing new physical connections to the database or using a connection pool (c3p0, bonecp, hikari or whatever implementation you like). After obtaining a Connection, it will use it to create a new EntityManager. The EntityManager can interact with your objects and your database using this Connection and can manage the transaction through calling EntityManager#getTransaction and then calling EntityTransaction#begin, EntityTransaction#commit and EntityTransaction#rollback that internally works with Connection#begin, Connection#commit and Connection#rollback respectively. This is plain vanilla JPA and Spring has nothing to do up to this point.
For transaction management, Spring helps you to avoid opening/closing the transactions manually by using a transaction manager, specifically a class called JpaTransactionManager. This transaction manager will make use of your EntityManagerFactory to open and close a transaction for the EntityManager created for a set of operations. This can be done either using XML configuration or #Transactional annotation on your classes/methods. When using this approach, you won't directly work with your specific classes anymore, instead Spring will create proxies for your classes using cglib and make use of the transaction manager class to open the transaction, call your specific method(s) and execute a commit or rollback at the end, depending on your configuration. Apart of this, Spring provides other configurations like read-only transactions (no data modification operation allowed).
Here's a basic configuration of the elements explained above using Spring/Hibernate/JPA:
<!--
Declare the datasource.
Look for your datasource provider like c3p0 or HikariCP.
Using most basic parameters. It's up to you to tune this config.
-->
<bean id="jpaDataSource"
class="..."
destroy-method="close"
driverClass="${app.jdbc.driverClassName}"
jdbcUrl="${app.jdbc.url}"
user="${app.jdbc.username}"
password="${app.jdbc.password}" />
<!--
Specify the ORM vendor. This is, the framework implementing JPA.
-->
<bean id="hibernateVendor"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
showSql="false"/>
<!--
Declare the JPA EntityManagerFactory.
Spring provides a class implementation for it.
-->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
persistenceXmlLocation="classpath*:META-INF/persistence.xml"
persistenceUnitName="hibernatePersistenceUnit"
dataSource-ref="jpaDataSource"
jpaVendorAdapter-ref="hibernateVendor"/>
<!--
Declare a transaction manager.
Spring uses the transaction manager on top of EntityManagerFactory.
-->
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager"
entityManagerFactory-ref="entityManagerFactory"/>
From what i see, your em reference should be a functioning proxy object to your database (this EntityManager is the thing that should be a spring bean, having configured everything, like DB url, driver, etc. Apart from this none of your code should depend on what DB you have). You don't need to know about the classes you mention (entitymanagerfactory sessionfactory transactionmanager). Easy example is:
List<MyBean> bean = (List<MyBean>)em.createNamedQuery("select * from mydb").getResultList();
It should be this easy to run a select * query and get your MyBean typed objects straight ahead, without any explicit conversion by you (this is what hibernate is for).
Similar for insert:
em.persist(myBean);
where myBean is something annotated for Hibernate.
Briefly about transactions, i found best to annotate #Transactional on service METHODS (you did it on a whole dao).
To be very very general:
an entitymanagerfactory is an object responsible of the creation of the entitymanager and it comes from the JPA specifications.
SessionFactory is the hibernate implementation of entitymanagerfactory
session is the hibernate implementation of entitymanager
A transacation manager is an object who manages transaction when you want to define a transaction manually.
So if you want to use hibernate, use SessionFactory and session. And if you want you to stay "generic" use the EntityManagerFactory.
http://www.javabeat.net/jpa-entitymanager-vs-hibernate-sessionfactory/
http://www.theserverside.com/tip/How-to-get-the-Hibernate-Session-from-the-JPA-20-EntityManager
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.
I have a method that I've annotated with the #Transactional annotation.
The problem is, the datasource that the code runs against can change! Briefly, is it possible to change the transaction's datasource while the application is running?
In depth:
The application lets users select a database to run sql against. They can change the database at runtime. I'd like the application to run all the sql in a transaction - the sql groups are always against the same datasource, so that's not an issue.
The issue is, I don't know how to changem the transaction to use a different datasource. Varying articles have suggested the JTATransactionManager, but we're on tomcat, so no dice.
Is there a simple way to do this, or will we need to ditch the #Transactional annotation and do something else?
And if so, what is that "something else?"
Oh, the database is db2, if that's any use!
thanks!
One of the possible solution
Configure all the possible datasources in spring config
a. Datasource1 for DB1
b. Datasource2 for DB2 etc..
Maintain a map of above datasource in a service class and create spring's JDBCTemplate out of selected datasource based on some key from map.