I think this is a situation where you want to use a custom
TypeConverter. Struts does not know how to convert your String id
property into a User object. Create a custom type converter for
com.yourapp.model.User (or org.appfuse.model.User) that looks up the
User in the db based on String id when going from String > Object and
then sends out the user.getId() is the Object > String conversion. It
is not a cascade issue, since you really don't want to update the
owning User object (no change to the User). You just want to update
the owner on the task.
public class UserConverter extends StrutsTypeConverter {
private UserManager userManager;
private static final Log log =
LogFactory.getLog(UserConverter.class);
public void setUserManager(UserManager userManager) {
this.userManager = userManager;
}
public Object convertFromString(Map map, String[] value, Class
aClass) {
if (value[0] == null || value[0].trim().equals("")) {
return null;
}
try {
return userManager.getUserByUsername(value[0]);
} catch (UsernameNotFoundException e) {
e.printStackTrace();
throw new TypeConversionException(e.getMessage());
}
}
public String convertToString(Map map, Object o) {
return ((User) o).getUsername();
}
In WEB-INF/classes there is a file called xwork-
conversion.properties. Register your converter there with:
org.appfuse.model.User=com.jmh.hcc.webapp.action.UserConverter
-D
On May 15, 2008, at 10:36 AM, java_user_ wrote:
Was a solution found?
The issue is that hibernate is trying to update the lookup table
(user)
instead of updating the entity table's (owner) foreign key to the
lookup
table.
What is the correct cascade to use in the ManyToOne annotation of
the Owner
model and the OneToMany annonation of the User model for this O/R
mapping
situation?
sarat.pediredla wrote:
The problem is simple,
I have an object called Task which has a property called owner that
is
mapped as follows,
@ManyToOne
(cascade={CascadeType.PERSIST,CascadeType.REFRESH,CascadeType.MERGE})
@Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE,
org.hibernate.annotations.CascadeType.MERGE,
org.hibernate.annotations.CascadeType.PERSIST})
public User getOwner() {
return owner;
}
I have a JSP page in my Struts 2 appfuse app as follows,
<s:textfield name="name" label="name" theme="xhtml"/>
<s:select key="owner.id" list="users" listKey="id"
listValue="fullName" multiple="false" size="1"
theme="xhtml"/>
When I post this, everything is wired up ok until I call
TaskManager.save(task) in my Action when I get the following error,
Stacktraces
org.springframework.orm.hibernate3.HibernateSystemException:
identifier of
an instance of org.appfuse.model.model.User was altered from 2 to 11;
nested exception is org.hibernate.HibernateException: identifier of
an
instance of org.appfuse.model.User was altered from 2 to 11
org
.springframework
.orm
.hibernate3
.SessionFactoryUtils
.convertHibernateAccessException(SessionFactoryUtils.java:659)
org
.springframework
.orm
.hibernate3
.HibernateTransactionManager
.convertHibernateAccessException(HibernateTransactionManager.java:
690)
org
.springframework
.orm
.hibernate3
.HibernateTransactionManager
.doCommit(HibernateTransactionManager.java:566)
org
.springframework
.transaction
.support
.AbstractPlatformTransactionManager
.processCommit(AbstractPlatformTransactionManager.java:662)
org
.springframework
.transaction
.support
.AbstractPlatformTransactionManager
.commit(AbstractPlatformTransactionManager.java:632)
org
.springframework
.transaction
.interceptor
.TransactionAspectSupport
.commitTransactionAfterReturning(TransactionAspectSupport.java:319)
org
.springframework
.transaction
.interceptor
.TransactionInterceptor.invoke(TransactionInterceptor.java:116)
org
.springframework
.aop
.framework
.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:
171)
org
.springframework
.aop
.interceptor
.ExposeInvocationInterceptor
.invoke(ExposeInvocationInterceptor.java:89)
org
.springframework
.aop
.framework
.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:
171)
org
.springframework
.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
$Proxy70.save(Unknown Source)
Surely given that I have configured cascading for the persistence
correctly, should the owner object not be refreshed dynamically
instead of
trying to overwrite the id of the existing object?
What is the best way around this short of me having to use a temp
var like
frmOwner and assigned task.setOwner which is not really an option
as I
want to pursue a REST architecture.
--
View this message in context:
http://www.nabble.com/Updating-a-related-entity-in-Struts-2-throws-HibernateException-tp15923014s2369p17258605.html
Sent from the AppFuse - User mailing list archive at Nabble.com.
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]