2012-06-21 59 views
1

我有一个表单来添加新的Appartments,并且在这个表单中我有一个下拉框,用户可以选择哪个人负责。对象是一个未保存的瞬态实例 - 在合并之前保存瞬态实例

当我们从下拉列表中选择并尝试保存该公寓时,我的申请会认为该人已被修改。它给了我下面的错误表明我应该先保存这个人。但该人没有修改。只有公寓才能被保存并提及另一个人。

object is an unsaved transient instance - save the transient instance before merging

我怎样才能让我的应用程序了解该人本人没有被修改。只有公寓?

这里是我的代码:

@Entity 
@Table(name = "Person") 
public class Person{ 
    @Id 
    private Long id; 
    private String fullName; 
    .... 
} 

@Entity 
@Table(name = "Appartment") 
public class Appartment{ 
    .... 
    @ManyToOne (fetch = FetchType.LAZY) 
    @JoinColumn (name = "client_contact_person_id") 
    private Person clientResponsiblePerson; 
} 

动作加载所有的人加入列表responsiblePersons。

而JSP:

<s:select name="appartment.clientResponsiblePerson.id" list="responsiblePersons" 
     listKey="id" listValue="fullName" headerKey="-1" 
     label="%{getText('appartment.clientContact.ourContact')}" headerValue="%{getText('person.choose')}" 
     required="true" cssClass="select medium" /> 

任何想法?我一直在寻找和调试了几个小时,没有任何解决方案... :(

UPDATE:。 史蒂芬建议我从appartment.clientResponsiblePerson.id删除ID这是一个合理的建议,我也只是尝试,但后来似乎像我的应用程序不知道如何映射提交表单的人对象的值作为即时通讯设定listKey="id"提交的价值是人的ID

我收到以下错误:。 Invalid field value for field "appartment.clientResponsiblePerson".

tag 'select', field 'list', name 'appartment.clientResponsiblePerson': The requested list key 'responsiblePeople' could not be resolved as a collection/array/map/enumeration/iterator type. Example: people or people.{name} - [unknown location]

所以我最初的想法是,也许我应该从我的s:select中删除listKey和listValue。也许struts自动检测对象的id,并使用toString作为值?但我没有更多的运气,也试过这个。

另一个非常奇怪的事情是,我用另一种形式做完全相同的事情。在这种形式下,我从下拉列表中选择区域。我正在使用appartment.area.id作为名称。它在那里完美运作。奇怪..我还检查了Area - Appartment的参考资料没有设置为自动持续或合并。

它让我觉得我正在努力实现的应该是真正的直截了当。这是什么,我不在这里?

+0

您作为更新发布的消息意味着传递给列表属性(responsiblePersons)的值不是“集合/数组/映射/枚举/迭代器”。除非更改了动作的getResponsiblePersons()方法,或者更改了s:select标签上的列表属性的值,否则不应该出现该错误。 –

回答

1

当我们从下拉列表中选择并尝试保存公寓时,我的申请会认为人员已被修改。

这正是你的代码所做的。以下行是罪魁祸首:

appartment.clientResponsiblePerson.id 

这是告诉Struts2框架把你在选择降下来的人的ID,并把它传递给getAppartment().getClientResponsiblePerson().setId(id)。这不会改变为新的负责人,它会改变现有人的主键。调用setClientResponsiblePerson(Person)会改变这个人。

尝试使用appartment.clientResponsiblePerson,而不是看看它是如何工作的。

更新

另一种非常奇怪的事情是,我做同样的事情的另一种形式。

我不明白这是怎么回事。

Struts2的不知道Person是什么,所以你有几种选择:

  1. 创建的类型转换告诉Struts2的如何从“1”转换(或无论是从下拉列表中传递)到Person的一个实例。
  2. 增加您的行动setPerson(Integer)方法,该方法将查找基于传入的整数主键适当的Person实体,然后更新您的S:选择<s:select name="person" list="responsiblePersons" .../>

就个人而言,我用#1。

+0

感谢您的回答。刚刚尝试过,它给了我另一个新的错误。请参阅我更新的答案以获取更多详细信息 – user829237

+0

请提供您的s:select的更新代码。你仍然需要listKey和listValue,它们驱动下拉菜单中的内容,与Struts2在后端做什么无关。 –

+0

感谢您的更新史蒂文。只要我得到时间并发布结果,我会尽快完成。但我认为你只是给了我我想念的解决方案:)不知道为什么其他形式的作品虽然..但这是一个不同的故事。 – user829237

相关问题