Answer the question
In order to leave comments, you need to log in
Clarification in Spring+Hibernate(JPA) configuration. Assistance in setting up transactions. Why don't they pass?
Welcome all! As a beginner in programming, I had difficulties in mastering new technologies. Moving from bare Jdbc + servlets to Hibernate + Spring, I faced, as it seemed to me, with a whole iceberg (google is already all purple), and the biggest difficulty is to correctly connect all the components. Of course, as they say, I could use Spring Boot, and it would solve many of my problems, but still I really want to understand what I'm doing (after all, I'm already at a high level of abstraction). In general, my question is complex, and I hope for your help guys:
First, a couple of questions about the configuration file, here is my mvc-spring-dispatcher.xml :
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/mydbtest"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="com.springapp.mvc"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<bean id="persistenceExceptionTranslationPostProcessor"
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<tx:annotation-driven transaction-manager="transactionManager"/>
import javax.persistence.*;
@Entity
@Table(name = "person")
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
@Column(name = "id" )
private Integer id;
@Column(name = "name", length = 40 )
private String name;
@Column(name = "email", length = 100 )
private String email;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", email=" + email + "]";
}
}
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import com.springapp.mvc.Entities.Person;
import org.springframework.stereotype.Repository;
@Repository("personDao")
public class PersonDao {
@PersistenceContext
private EntityManager entityManager;
public EntityManager getEntityManager() {
return entityManager;
}
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
public void insert(Person person) {
entityManager.persist(person);
}
public List<Person> selectAll() {
Query query = entityManager.createQuery("");
List<Person> persons = (List<Person>) query.getResultList();
return persons;
}
}
package com.springapp.mvc.Service;
import java.util.List;
import com.springapp.mvc.DAO.PersonDao;
import com.springapp.mvc.Entities.Person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@Service
public class PersonService {
private PersonDao personDao;
public PersonDao getPersonDao() {
return personDao;
}
@Autowired
public void setPersonDao(PersonDao personDao) {
this.personDao = personDao;
}
@Transactional(propagation = Propagation.REQUIRED)
public void addPerson(Person person) {
getPersonDao().insert(person);
}
public List<Person> fetchAllPersons() {
return getPersonDao().selectAll();
}
}
@RequestMapping(value = "/superData", method = RequestMethod.POST , produces= MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<PeopleEntity> peopleEntity(@RequestBody Person transform) {
System.out.println(transform);
PersonService service=new PersonService();
service.addPerson(transform);
PeopleEntity peopleEntity = new PeopleEntity();
peopleEntity.setFirstName("John");
peopleEntity.setLastName("Dorian");
return new ResponseEntity<PeopleEntity>(peopleEntity, HttpStatus.OK);
}
CREATE TABLE `person` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(40) NOT NULL,
`email` varchar(100) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
CREATE TABLE `hibernate_sequences` (
`sequence_name` varchar(255) NOT NULL,
`next_val` bigint(20) DEFAULT NULL,
PRIMARY KEY (`sequence_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
And in this case, it should put down the id itself in accordance with the counter in the table? "email", length = 100 )
(name = @Repository
- it is like an extended @Component, only with extended features: it throws out its own special events, it matters as a logical component for the developer (i.e. a person will see that this is a DAO layer class). What is the purpose of the value specified in the annotation, in this case @Repository("personDao")
? @PersistenceContext
- as I understand it, it automatically injects the EntityManager, which I chose and configured here in the beans: org.springframework.orm.jpa.JpaTransactionManager? That is, it removes the template actions for creating a manager for transactions, starting from createEntityManager, to getTranssaction().begin()? @Transaction
- is activated and in turn commits all transactions and then closes? Optionally, can you do a rollback, in case of failure? What does (propagation = Propagation.REQUIRED) mean?Of course, I found several explanations, but without an example, it is not entirely clear how it works and in general for what. Answer the question
In order to leave comments, you need to log in
I won’t tell you for all of Odessa, but in Siberia it is believed that
1) @GeneratedValue(strategy = GenerationType.TABLE)
- says that you need to use a table to generate PK. Not the table onto which the entity is mapped, but just a table. This is where the hibernate_sequences table comes from. And it occurs because of hibernate.hbm2ddl.auto=update.
2) About the length of the column, this is again due to hibernate.hbm2ddl.auto=update.
3) @Transaction
says the method will be transactional. What does it mean. This means that the method call will be wrapped in a proxy object that will have a session, and when all nested methods are called, this session will be the same, and when the method ends, the transaction will be closed.
4) propagation = Propagation.REQUIRED
- this means that the presence of a session when calling the method is mandatory, if it is not there, then hibernate will try to create it.
5) Transaction rollback (roughly speaking rollbak) occurs, by default, only in case of occurrence RuntimeException
, how to manage it is written in the documentation for hibernate.
6) the value in the annotation @Repository("personDao")
specifies the name of the bean.
Now, according to the classics, something needs to be advised. I advise you not to use hibernate.hbm2ddl.auto=update. Better look towards liquibase for database state management.
And read introductory tutorials on Spring, understand how IoC works in Spring, how AOP works in Spring, how Spring manages beans. And then everything will become clear to you.
Go for it, good luck to you!
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question