JPA relation Persistence
I am using JPA 2 with following jars on class path
[INFO] +- org.aspectj:aspectjrt:jar:1.6.9:compile
[INFO] +- org.aspectj:aspectjweaver:jar:1.6.9:compile
[INFO] +- org.springframework:spring-aspects:jar:3.1.0.M2:compile
[INFO] | +- org.springframework:spring-beans:jar:3.1.0.M2:compile
[INFO] | | \- org.springframework:spring-core:jar:3.1.0.M2:compile
[INFO] | \- org.springframework:spring-context-support:jar:3.1.0.M2:compile
[INFO] +- com.googlecode.commonspringaspects:common-spring-aspects:jar:1.0.9:compile
[INFO] | +- net.sf.ehcache:ehcache-core:jar:1.7.2:compile
[INFO] | \- com.jamonapi:jamon:jar:2.4:compile
[INFO] +- com.jamon:jamonapi:jar:2.73:compile
[INFO] +- javax.validation:validation-api:jar:1.0.0.GA:compile
[INFO] +- org.springframework:spring-context:jar:3.1.0.M2:test (scope not updated to compile)
[INFO] | +- org.springframework:spring-aop:jar:3.1.0.M2:test
[INFO] | | \- aopalliance:aopalliance:jar:1.0:test
[INFO] | +- org.springframework:spring-expression:jar:3.1.0.M2:test
[INFO] | \- org.springframework:spring-asm:jar:3.1.0.M2:test
[INFO] +- org.springframework:spring-orm:jar:3.1.0.M2:test
[INFO] | +- org.springframework:spring-jdbc:jar:3.1.0.M2:test
[INFO] | \- org.springframework:spring-tx:jar:3.1.0.M2:test
[INFO] +- org.mockito:mockito-all:jar:1.9.0-rc1:test
[INFO] +- dirty-mockito:dirty-mockito:jar:0.4:test
[INFO] +- org.hibernate:hibernate-validator:jar:4.2.0.Final:test
[INFO] +- org.hsqldb:hsqldb:jar:2.2.4:compile
[INFO] +- org.hibernate:hibernate-entitymanager:jar:3.6.2.Final:compile
[INFO] | +- org.hibernate:hibernate-core:jar:3.6.2.Final:compile
[INFO] | | +- antlr:antlr:jar:2.7.6:compile
[INFO] | | +- commons-collections:commons-collections:jar:3.1:compile
[INFO] | | +- dom4j:dom4j:jar:1.6.1:compile
[INFO] | | +- org.hibernate:hibernate-commons- annotations:jar:3.2.0.Final:compile
[INFO] | | \- javax.transaction:jta:jar:1.1:compile
[INFO] | +- cglib:cglib:jar:2.2:compile
[INFO] | | \- asm:asm:jar:3.1:compile
[INFO] | +- javassist:javassist:jar:3.12.0.GA:compile
[INFO] | \- org.hibernate.javax.persistence:hibernate-jpa-2.0- api:jar:1.0.0.Final:compile
[INFO] +- javax.inject:javax.inject:jar:1:compile
[INFO] +- junit:junit:jar:4.8.1:test
[INFO] +- org.springframework:spring-test:jar:3.1.0.M2:test
[INFO] +- commons-logging:commons-logging:jar:1.1.1:compile
[INFO] +- org.slf4j:slf4j-api:jar:1.5.10:compile
[INFO] +- org.slf4j:jcl-over-slf4j:jar:1.5.10:compile
[INFO] +- org.slf4j:slf4j-log4j12:jar:1.5.10:compile
[INFO] \- log4j:log4j:jar:1.2.15:compile
and my model is as follows
<access>FIELD</access>
<mapped-superclass class="com.compnay.qube.foundation.core.model.BaseModel">
<attributes>
<id name="uid">
<column name="UID" nullable="false" />
<generated-value strategy="AUTO" />
</id>
<basic name="creationDate">
<column name="CREATIONDATE" updatable="false" nullable="false" />
<temporal>TIMESTAMP</temporal>
</basic>
<basic name="modificationDate">
<column name="MODIFICATIONDATE" updatable="true" nullable="true"
column-definition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP" />
<temporal>TIMESTAMP</temporal>
</basic>
<one-to-many name="changeLog">
<cascade>
<cascade-persist />
<cascade-merge />
<cascade-refresh />
</cascade>
</one-to-many>
<!-- <element-collection name="changeLog" fetch="LAZY"> </element-collection> -->
</attributes>
</mapped-superclass>
<entity class="com.compnay.qube.services.core.user.model.User"
name="User">
<table name="USER" />
<inheritance strategy="JOINED" />
<named-query name="findUserByUserName">
<query><![CDATA[select user from User user where
user.userName = :userName]]></query>
</named-query>
<attributes>
<basic name="userName">
<column name="USERNAME" length="100" updatable="false"
unique="false" />
</basic>
<basic name="passsword">
<column name="PASSWORD" length="100" updatable="false"
unique="false" />
</basic>
<basic name="email">
<column name="EMAIL" length="100" updatable="false" unique="false" />
</basic>
<basic name="optIn">
<column name="OPTIN" updatable="true" unique="false" />
</basic>
<one-to-many name="userRoles">
<join-table name="USER_ROLES">
<join-column name="USER_ID" />
<inverse-join-column name="ROLE_ID" />
</join-table>
<cascade>
<cascade-persist />
<cascade-merge />
<cascade-refresh />
</cascade>
</one-to-many>
</attributes>
</entity>
<entity class="com.compnay.qube.ser开发者_如何学编程vices.core.user.model.Role"
name="ROLE">
<table name="ROLE" />
<inheritance strategy="JOINED" />
<named-query name="findByUniqueName">
<query><![CDATA[select role from ROLE role where role.roleName = :roleName]]></query>
</named-query>
<attributes>
<basic name="roleName">
<column name="ROLE" length="100" updatable="true" unique="true" />
</basic>
<!--<transient name="user" /> -->
<many-to-one name="user">
<cascade>
<cascade-all />
</cascade>
</many-to-one>
</attributes>
</entity>
Base DAO has method
public void create(M model) throws DAOException {
try {
entityManager.persist(model);
} catch (RollbackException rollBackExp) {
ErrorCode errorCode = new ErrorCode();
// SQLException sqle = (SQLException) pExp.getCause().getCause();
// errorCode = errorHandler.getErrorCode(sqle);
// errorCode.setCode(sqle.getErrorCode() + "");
throw new DAOException(errorCode, rollBackExp);
} catch (PersistenceException pExp) {
ErrorCode errorCode = new ErrorCode();
// SQLException sqle = (SQLException) pExp.getCause().getCause();
// errorCode = errorHandler.getErrorCode(sqle);
// errorCode.setCode(sqle.getErrorCode() + "");
throw new DAOException(errorCode, pExp);
}finally{
entityManager.flush();
}
}
and services just delegates it to dao for now wrapped in transaction by spring. when i run my test to persist User only it works fine but when i add userRoles to the user
if(roles.size() == 0){
Role arole = initRole(RoleType.ADMIN.name(),
CREATION_DATE_YESTERDAY, MODIFICATION_DATE_TODAY);
Role srole = initRole(RoleType.SUPER_USER.name(),
CREATION_DATE_YESTERDAY, MODIFICATION_DATE_TODAY);
Role urole = initRole(RoleType.USER.name(),
CREATION_DATE_YESTERDAY, MODIFICATION_DATE_TODAY);
roles.put(arole.getRoleName(), arole);
roles.put(srole.getRoleName(), srole);
roles.put(urole.getRoleName(), urole);
}
User user_one = initUser("user" + (i+1) , "user" + (i+1), "user" + (i+1) + "@user.com",
CREATION_DATE_YESTERDAY, MODIFICATION_DATE_TODAY);
user_one.setUserRoles(new HashSet<Role>(roles.values()));
Enumeration<String> roleKeys = roles.keys();
while(roleKeys.hasMoreElements()){
String key = roleKeys.nextElement();
Role role = roles.get(key);
role.setUser(user_one);
}
try {
userService.create(user_one);
Set<Role> urole = user_one.getUserRoles();
for (Role role : urole) {
roles.put(role.getRoleName(), role);
}
//logger.debug(user_one);
} catch (ServiceException e) {
e.printStackTrace();
}
It thorws an exception in second iteration
java.sql.BatchUpdateException: Duplicate entry '3' for key 'ROLE_ID'
ERROR: org.hibernate.util.JDBCExceptionReporter - Duplicate entry '3' for key 'ROLE_ID'
org.hibernate.util.JDBCExceptionReporter - SQL Error: 1062, SQLState: 23000
Can someone suggest what is wrong with this bit of code.
Can't use annotations as this is mapping legacy code being used in various applications
精彩评论