I have hibernated annotated classes in my program. Since I'm running a Spring project, I have included them in the servlet.xml file(com.student.dto is the actual package name) and added #Component on the Contacts Entity..Is there a way to automate adding #Component on all the hibernate classes..Each time I create a model, I end up doing this and feel there should be a better to do this.
<context:component-scan base-package="com.student.dto" />
#Component
#Entity
#Table(name = "Contacts", catalog = "javadb")
public class ContactsDTO implements java.io.Serializable {
private int idContacts;
private StudentDTO StudentDTO;
private String addr1;
private String addr2;
private String city;
private String state;
private String pinCode;
private String country;
private String phone;
private String mobile;
private String email;
private String contactscol;
public ContactsDTO() {
}
public ContactsDTO(int idContacts) {
this.idContacts = idContacts;
}
public ContactsDTO(int idContacts, StudentDTO StudentDTO, String addr1,
String addr2, String city, String state, String pinCode,
String country, String phone, String mobile, String email,
String contactscol) {
this.idContacts = idContacts;
this.StudentDTO = StudentDTO;
this.addr1 = addr1;
this.addr2 = addr2;
this.city = city;
this.state = state;
this.pinCode = pinCode;
this.country = country;
this.phone = phone;
this.mobile = mobile;
this.email = email;
this.contactscol = contactscol;
}
getters & setters
You are doing it all wrong. Spring Beans are singleton by default and your entities are not thread safe and neither they should ever be.
Entities should be local variables bound to a Persistent Context. They are not meant to be accessed in a multi-threaded environment.
Concurrency control is handled by the database and your application logic should mostly be concern about preventing lost updates through application-level repeatable reads.
Your DAO and Services should be Spring singleton components. Your Entities and request bound DTOs should never be singleton. These objects are short-lived and scoped to the request that generated them.
Check the Spring Data JPA docs for a solid data access layer design.
The #Component javadocs says this.
Indicates that an annotated class is a "component". Such classes are considered as candidates for auto-detection when using annotation-based configuration and classpath scanning.
The #Component, #Repository etc are Typically used for Auto scanning (during application bootstrap)and for the dependency injection. I dont see a point in making your entity as a Spring Component. The typical use of an entity is that it represents your Relational database Table. Entity (Java)= Table (RDBMS). Here is the definition of an Entity
An entity is a lightweight persistence domain object. Typically, an entity represents a table in a relational database, and each entity instance corresponds to a row in that table. The primary programming artifact of an entity is the entity class, although entities can use helper classes.
The way to include your entities should be something like this:
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
<prop key="hibernate.jdbc.batch_size">${hibernate.jdbc.batch_size}</prop>
</props>
</property>
<property name="annotatedClasses">
<list>
<!-- Here are your Entities annotated with #Entity -->
</list>
</bean>
Note that you can also define a property called "annotatedPackages" and define your packages
Personally, i havent tested "annotatedPackages". But, "annotatedClasses" work perfectly.
As suggested by #Vlad Mihalcea, Entities are not meant to be Singleton. They are more of "Local" scope, and are to be intialized per "request".
You can configure this by convention. In the servlet.xml you can add a bean that does class path scanning and can automatically add the #Component using a regex and a common naming approach. See here for details:
http://www.mkyong.com/spring/spring-filtering-components-in-auto-scanning/
Related
I have a class MyBean with some fields including String "id".
I have a lot of xml-defined beans with IDs.
I want to fill "id" fields of MyBean java objects to xml-specified bean IDs. How to implement this without code duplicaton?
package just.artmmslv.example.MyBean
public class MyBean {
private String id;
private String foo;
//getters, setters, other fields
}
<beans xmlns="foobar+util">
<util:list value-type="just.artmmslv.example.MyBean">
<bean id="exampleBean01" class="just.artmmslv.example.MyBean">
<property name="foo" value="bar"/>
</bean>
<!--Other beans-->
</util:list>
</beans>
So, how to make exampleBean01`s field id to be equal to "exampleBean01" in convenient way?
Make id in MyBean of type String, not int (I see int in your code)
Make MyBean implements BeanNameAware
Implement method setBeanName in MyBean:
#Override
public void setBeanName(String s) {
this.id = s;
}
That's all you need
I think Spring provides a way to do this via BeanNameAware.
Read through: https://docs.spring.io/spring/docs/2.5.x/reference/beans.html#beans-factory-aware-beannameaware
Interface to be implemented by beans that want to be aware of their bean name in a bean factory. Note that it is not usually recommended that an object depend on its bean name, as this represents a potentially brittle dependence on external
configuration, as well as a possibly unnecessary dependence on a Spring API.
I am currently working on a JavaSE project that I would like to build in the most effective way. My project is an employeeManagementSystem which has several schemas. For example I have one schema called employees which contains employee data and another schema called company which contains the company data.
Currently I have implemented my entities and tested these using hibernate.cfg.xml to make sure they are implemented correctly. For example, one such entity in the employee schema is
#Entity
#Table(name="employees", uniqueConstraints= {
#UniqueConstraint(columnNames="idEmployees"),
#UniqueConstraint(columnNames="idCardNumber"),
#UniqueConstraint(columnNames="niNumber")
})
public class Employee {
#Id
#GeneratedValue
#Column(unique=true, nullable=false, updatable=false)
private int idEmployees;
#Column(unique=true, nullable=false, updatable=false)
#Size(min=1, max=15)
private String idCardNumber;
#Column(unique=true, nullable=false, updatable=false)
#Size(min=1, max=15)
private String niNumber;
#Column(nullable=false, updatable=false)
#Size(min=1, max=20)
private String name;
#Column(nullable=false)
#Size(min=1, max=20)
private String surname;
// Other class variables
//Constructors
//getters & setters
}
I an now trying to use an EntityManager to manage my schemas. My persistence.xml for the employee schema is
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="EmployeesDAO" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.shopmanagementsystem.employeesdao.entities.Employee</class>
//Other classes in this schema
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="root"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/employees"/>
</properties>
</persistence-unit>
</persistence>
I want to create a Service and ServiceImpl class to manage the processes related to the entities.
Q1) Should I have a Service and ServiceImpl for each entity?
Some of my questions were answered already in a previous post JPA EntityManager Construction
Q2) I further asked about using #PersistenceContext and was kindly advised to ask another question with a more detailed description of my project.
I am happy to add more details if I've left anything out and thank you for your advice and help.
Q1) Should I have a Service and ServiceImpl for each entity?
Not necessarily. Based on the name of the persistence unit: EmployeesDAO, I'm assuming that Service and ServiceImp are intended to implement DAO pattern, right? In this context you have to offer a contract (INSERT / UPDATE/ DELETE / QUERY) just for those entities that actually require it. For example you can have a table called Category which has a relationship with Employee like this:
#Entity
#Table(name="categories")
public class Category implements Serializable {
...
#Id private BigInteger idCategory;
#Basic private String description;
...
}
#Entity
#Table(name="employees")
public class Employee implements Serializable {
...
#ManyToOne
#JoinColumn(name="idcategory", referencedColumnName="idcategory")
private Category category;
...
}
In this example you would have a Service to manage Category entities only if you need to. If those entities are managed by another application then you just need to have read privileges on categories table so the entity manager can map this data and that's it.
Q2) I further asked about using #PersistenceContext and was kindly advised to ask another question with a more detailed description of my
project.
First of all please beware that #PersistenceContext annotation is intended to be used with container-based persistence, as part of a Java EE application. You cannot use this annotation in plain Java SE platform.
On the other hand it doesn't mean you can't use JPA. Yes, it's perfectly possible, but you have to take care of the whole entity managers life-cycle. It is a common practice in this case to implement design patterns (such as Abstract Factory or Factory method or Singleton) in order to instantiate/access your entity managers manually.
In addition if you want to develop the top level layers of your application using Java SE and use container-managed persistence, then you can code the persistence layer using JPA and Enterprise JavaBeans architecture. This approach is not simple but has several advantages:
You can offer the persistence layer as a service through EJB modules.
Database connections and pools can be managed by the EJB container. This is extremely useful to separate database connection info from persistence.xml file.
As already mentioned, the EJB container will manage the whole entity manager life-cycle.
You can go further and leave container use Java Transaction API so you can forget (more or less) about transactional stuff.
Other comments
I know that posted persistence.xml is probably just an example but I have to mention that connect to the database as root user is not a good practice at all. Due to security reasons you should have several users with the right privileges to access your database, and likely none of them will ever need super-user privileges.
Finally, applications design is a really broad topic and it can be simple or complex based on your requirements. In addition there are several frameworks/technologies that can be used and is very very easy to get lost if you don't have any experience. My suggestion if you never did something like this before is to start with a very basic application and then go further.
I am facing a problem with Spring Transaction management. I am using hibernate as ORM framework. And below is my spring for transaction management.
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
<bean id="abstractDao"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true" lazy-init="true">
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
<property name="transactionAttributeSource">
<ref bean="transactionAttributeSource"/>
</property>
<property name="postInterceptors">
<list>
<ref bean="finderIntroductionAdvisor"/>
</list>
</property>
</bean>
<bean id="abstractService"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true" lazy-init="true">
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
<property name="transactionAttributeSource">
<ref bean="transactionAttributeSource"/>
</property>
</bean>
I am basically following genericDao approach as mentioned here so My DaoObject are used to fetch the Domain objects and service classes have DAO objects to maipulate them.
issue i am facing : i am querying a large dataset and loading the result in a list inside the service class. i have marked service class as #transactional(readonly ="true").
to handle some reuirement i have changed all the getters of boxed primitive to
#Column(name = "students")
public Long getStudents() {
if(students== null){
return 0l;
}
return this.students;
}
whenever i load all the dataset via a named query. multiple update queries are fired subsequently to update the dataset.
I debugged that and came to know that this is occuring because of transaction.commit. as hibernate is treating my entities as dirty.
is there a way i can avoid this . i know Flushmode.never could be of help but in my application seesion object is not exposed so i do not have access to it. is there any other way or some mapping change which can help me ?
In addition to Xavi López's answer, another option is to separate persistent property handled by Hibernate from the transient property that conform to your requirement. For example, as follows:
#Column(name = "students")
public Long getStudentsInternal() {
return students;
}
#Transient
public Long getStudents() {
if (students == null) {
return 0l;
}
return students;
}
You can also configure Hibernate to use fields instead of properties by moving annotations to them, it will solve your problem as well (note that the placement of annotations should be consitent for all fields of the entity, or you can use #Access to configure an exclusion):
#Column(name = "students")
private Long students;
public Long getStudents() {
if (students == null) {
return 0l;
}
return students;
}
The issue is with
if(students== null){
return 0l;
}
When Hibernate fetches your entities, they all have null value on the studentsfield. At commit time, when checking if they are dirty, getStudents() returns 0, which is different from the value stored in the database. So, Hibernate sees them as dirty, and proceeds to the update.
If it is suitable to your requirement, changing the type of the studentfield to the primitive type long instead of Long would probably help. Note that this would lead to updating all null's in that column to 0 in the long term.
Maybe you should handle that requirement somewhere else, and free the getter from that concern.
I am currently trying to replace my own database controller implementation with Hibernate and I have the following problem creating an appropriate mapping file.
(I am very new to Hibernate, so please be gentle :-) - I've read through the whole Hibernate Reference documentation but I don't have any practical experience yet).
(The whole thing should represent the relationship between email accounts and their server settings).
I have a class called MailAccount which has 2 properties (see code below):
public class MailAccount{
long id;
IncomingMailServer incomingServer;
OutgoingMailServer outgoingServer;
public MailAccount(){
super();
}
// Getter and setter omitted
}
The server class hierachy looks like this:
MailServer.java
public abstract class MailServer {
String password;
String host;
String username;
String port;
// Getter and setter omitted
}
IncomingMailServer.java
public abstract class IncomingMailServer extends MailServer {
}
OutgoingMailServer.java
public abstract class OutgoingMailServer extends MailServer {
}
Pop3Server.java
public class Pop3Server extends IncomingMailServer{
public Pop3Server(){
super();
}
}
ImapServer.java
public class ImapServer extends IncomingMailServer{
public ImapServer(){
super();
}
}
SmtpServer.java
public class SmtpServer extends OutgoingMailServer{
public SmtpServer(){
super();
}
}
The properties incomingServer and outgoingServer in MailAccount.java of course only hold instances of either Pop3Server, ImapServer (for incomingServer) or SmtpServer (for outgoingServer).
Now, I tried to create the mapping file for MailAccount:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="test.account">
<class name="MailAccount" table="MAILACCOUNTS" dynamic-update="true">
<id name="id" column="MAIL_ACCOUNT_ID">
<generator class="native" />
</id>
<component name="incomingServer" class="test.server.incoming.IncomingMailServer">
<property name="password" column="INCOMING_SERVER_PASSWORD" />
<property name="host" column="INCOMING_SERVER_PASSWORD" />
<property name="username" column="INCOMING_SERVER_PASSWORD" />
<property name="port" column="INCOMING_SERVER_PASSWORD" />
</component>
<component name="outgoingServer" class="test.server.outgoing.OutgoingMailServer">
<property name="password" column="OUTGOING_SERVER_PASSWORD" />
<property name="host" column="OUTGOING_SERVER_PASSWORD" />
<property name="username" column="OUTGOING_SERVER_PASSWORD" />
<property name="port" column="OUTGOING_SERVER_PASSWORD" />
</component>
</class>
</hibernate-mapping>
Note: Since I got a 1:1 relation between MailAccount and IncomingMailServer as well as MailAccount and OutgoingMailServer, I want everything in 1 table in order to prevent unnecessary joins.
The problem: Whenever I tell Hibernate to save an instance of MailAccount, like this:
session = getSession();
transaction = session.beginTransaction();
session.save(mailAccount);
transaction.commit();
.. I get the following exception:
org.hibernate.InstantiationException:
Cannot instantiate abstract class or
interface:
test.server.incoming.IncomingMailServer
This totally makes sense since abstract classes cannot be instantiated.
However, here comes my question: How can I tell Hibernate to create an instance of the right class (Pop3Server, SmtpServer, ImapServer) instead of the abstract ones?
Example: If the property incomingServer holds an instance of Pop3Server, then Hiberante should store that into my database and when I load the according MailAccount back, I want Hibernate to recreate an instance of Pop3Server.
The problem is occurring because a component is not a stand-alone entity, but "a class whose instances are stored as an intrinsic part of an owning entity and share the identity of the entity". In JPA terms it is considered an Embeddable class. These classes are usually used to create a class object out of a number of table columns that would normally have to be stored as individual attributes in an entity (you can almost look at it as grouping).
While there are a number of benefits to this approach, there are some restrictions. One of these restrictions are that the component or embeddable cannot be an abstract class. The reason being that there isn't any way for hibernate to associate a particular concrete subclass with the value you are trying to store or read. Think of it this way: would you be able to tell what instance to create by only looking at the column data? It's usually not that straight forward, especially for the persistence engine.
In order to get the functionality you desire, you will want to look into storing MailServer data as a separate entity with its own primary key field. Doing so allows you to manage the data with subclasses using various inheritance methods such as including a DiscriminatorColumn or separate tables (depending on your configuration).
Here are some links that should help you with setting up these mappings and using entity inheritance:
One-to-One mapping example
(useful if not reusing MailServer
data.
Inheritance overview
Useful Hibernate examples (not
latest spec, but gives you good
overview)
Hope this helps.
http://www.vaannila.com/hibernate/hibernate-example/hibernate-example.html
If you were to use this approach using Hibernate (I personally prefer JPA-based Annotation configurations), you could configure MailServer as an abstract entity that would define the common column mappings between the classes and a DiscriminatorColumn (if using same table inheritance). The subclasses would be built off of this definition, adding custom attributes as needed.
i'm developing an application where all the pojos are exposed as interface but we map the real implementation class.we are using spring and JPA annotation.i'm about to test the one-to-one relationship and i'm having a light problem with the interface.
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionContainer' defined in class path resource [META-INF/model-config.xml]:
Cannot resolve reference to bean 'sessionFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'sessionFactory' defined in class path resource [META-INF/model-config.xml]:
Invocation of init method failed; nested exception is org.hibernate.AnnotationException:
#OneToOne or #ManyToOne on com.mycompany.project.subproject.model.UserAccountImpl.profile references an unknown entity: com.mycompany.project.
so before this class all the other mapped class are working as expected so i'll only post part of the applicationContext file that i named model-config.xml
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
</props>
</property>
<property name="annotatedClasses">
<list>
...
<value>com.mycompany.project.subproject.model.UserProfileImpl</value>
<value>com.mycompany.project.subproject.model.UserAccountImpl</value>
...
</list>
</property>
here are the two involved class UserProfileImpl.java and UserAccountImpl.java
//UserAccountImpl Class
#Entity
#Table(name ="USER_ACCOUNT")
public class UserAccountImpl implements UserAccount {
#Id #GeneratedValue
#Column(name="USER_ACCOUNT_ID")
private Long ID;
...
#OneToOne
#JoinColumn(name="USER_PROFILE_ID")
private UserProfile profile;
...
}
//UserProfileImpl class
#Entity
#Table(name="USER_PROFILE")
public class UserProfileImpl implements UserProfile {
#Id #GeneratedValue
#Column(name="USER_PROFILE_ID")
private Long ID;
....
#OneToOne(mappedBy="profile")
private UserAccount userAccount;
....
}
i'm still not very confortable with hibernate yet so i'm wondering if i should Change the UserProfile reference in UserAccountImpl to UserProfileImpl.Then again the same can happen in the UserProfileImpl for userAccount reference since it's a bidirectional navigation stuff.
What's the best option that will no break the consistency of the structure?
Thanks for reading this
You have these options:
You must tell Hibernate somehow which class to use for the interface UserAccount. Currently, the most simple solution is to use a concrete type instead of the interface in your UserProfileImpl.
You can use #Target to specify the implementation to use (see [the docs][1]).
You can map the field with a custom UserType. This allows to chose the mapping (which implementation to use for an interface) at runtime but you must write the code to copy the fields between your business objects and the DB yourself (no automatic mapping anymore).
You could try the following:
#OneToOne(mappedBy="profile", targetEntity=UserAccountImpl.class)
private UserAccount userAccount
Does UserProfile have to be a separate Entity? You could model this as a Component, and combine the UserAccount and UserProfile tables into one. Your object model would still have a separate UserProfile object, it would just be a value object owned by UserAccount.
Not every object has to be implemented as an Entity,and One-to-One mappings are quite rare in practice ....