简体   繁体   中英

Hibernate generates more queries than normal

I am developing a small spring+hibernate web project. Follow are some its snippets

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
    http://www.springframework.org/schema/beans     
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

<context:component-scan base-package="com.catb">
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<mvc:annotation-driven />

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
    destroy-method="close">
    <property name="driverClass" value="com.mysql.jdbc.Driver" />
    <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/catb_db" />
    <property name="user" value="root" />
    <property name="password" value="root" />
</bean>

<bean id="hibernate4AnnotatedSessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="annotatedClasses">
        <list>
            <value>com.catb.model.User</value>
        </list>
    </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            <prop key="hibernate.show_sql">true</prop>
        </props>
    </property>
</bean>

<bean id="userDAO" class="com.catb.dao.impl.UserDAOImpl">
    <property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory" />
</bean>

<tx:annotation-driven transaction-manager="transactionManager"/>

<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory" />
</bean>

SpringDispatcher-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
    http://www.springframework.org/schema/beans     
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

<context:component-scan base-package="com.catb.web" />
<mvc:annotation-driven />

<mvc:resources mapping="/resources/**" location="/resources/" />

<bean
    class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix">
        <value>/WEB-INF/views/</value>
    </property>
    <property name="suffix">
        <value>.jsp</value>
    </property>
</bean>

User.java - here is mapping class

@SuppressWarnings("serial")
@Entity
@Table(name = "user")
public class User implements Serializable {

 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 @Column(name = "id", unique = true, nullable = false)
 private Integer id;

 @Column(name = "username", nullable = false)
 private String username;

 @Column(name = "password", nullable = false)
 private String password;
}

UserDAO class

@Repository
public class UserDAOImpl implements UserDAO {

  private SessionFactory sessionFactory;

  public void setSessionFactory(SessionFactory sessionFactory) {
      this.sessionFactory = sessionFactory;
  }


  @Override
  public boolean addUser(User user) {
      Session session = sessionFactory.getCurrentSession();
      session.save(user);

      return true;
  }
}

and UserBO class

@Override
@Transactional
public void addUser(User user) {
    userDAO.addUser(user);  
}

When I was trying to insert a single user using userBO.addUser(user) in controller, I hit an this error intermittently

org.hibernate.exception.ConstraintViolationException: could not execute statement
org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:72)
org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126)
...
caused by
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '60' for key 'username'
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)

I understand that this error caused by inserting a new row having duplicated value in unique field (username). But when I was trying to debug by show_sql of Hibernate, it printed out 2 lines instead of only one (I just inserted an only user)

Hibernate: insert into user (id, password, username) values (?, ?, ?)
Hibernate: insert into user (id, password, username) values (?, ?, ?)

Obviously, the second insertion caused the exception because it add the same value as the first

Can anyone tell my why I hit this error and how to resolve it

Thanks in advance

Try adding a log into the addUser Service method, because it looks like the service was called twice.

Are you sure you don't trigger to save calls from your browser? Check the networking tab in your browser developer tools too.

With you current configuration, there's no other explanation for Hibernate to issue to INSERTS.

Are you sure you posted all relevant code? There is a position_id mentioned in the logs, but you didn't post anything related to position , there might be some mapping problems. To be sure, you can strip User entity really down to the fields you posted (username and password) and see if it still causes the exception.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM