Reputation: 269
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
Upvotes: 1
Views: 66
Reputation: 24433
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.
Upvotes: 1
Reputation: 154130
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.
Upvotes: 1