SSH框架,action的scope设置为prototype一个奇怪问题,求解

wyfeng0601 2014-09-18 07:03:16
我用SSH框架做权限管理时遇到一个奇怪问题:
用户表:T_USER
角色表:T_ROLE
菜单表:T_RESOURCE
角色用户表:T_USER_ROLE
角色资源表:T_ROLE_RESOURCE
我在修改角色时,如果Struts2的action 设置为@Scope("prototype")时,会删除角色用户表和角色资源表数据:
Hibernate: update T_ROLE set UPDATE_DATE=? where ID=?
Hibernate: delete from T_ROLE_RESOURCE where ROLE_ID=?
Hibernate: delete from T_USER_ROLE where ROLE_ID=?

如果去掉@Scope("prototype"),更新正常:
Hibernate: update T_ROLE set UPDATE_DATE=? where ID=?

角色表POJO如下:
@Entity
@org.hibernate.annotations.Entity(selectBeforeUpdate = true, dynamicInsert = true, dynamicUpdate = true)
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@Table(name = "T_ROLE")
public class Role extends AuditModel implements Serializable {
private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ID", nullable = false)
private Long id;

@Column(name = "NAME_ZH", length = 64, nullable = false)
private String nameZh;

@Column(name = "NAME_EN", length = 64, nullable = false)
private String nameEn;

@Column(name = "ROLE_CODE", length = 30, nullable = false)
private String roleCode;

@Column(name = "DESCRIPTION", length = 64)
private String description;

@ManyToMany(cascade = { CascadeType.MERGE }, fetch = FetchType.LAZY)
@JoinTable(name = "T_ROLE_RESOURCE", joinColumns = { @JoinColumn(name = "ROLE_ID") }, inverseJoinColumns = { @JoinColumn(name = "RESOURCE_ID") })
private Set<Resource> tsResources;

@ManyToMany(cascade = { CascadeType.MERGE }, fetch = FetchType.LAZY)
@JoinTable(name = "T_USER_ROLE", joinColumns = { @JoinColumn(name = "ROLE_ID") }, inverseJoinColumns = { @JoinColumn(name = "USER_ID") })
private Set<User> tsUsers = new HashSet<User>(0);

@Transient
private Boolean ischecked = false;

public Role() {

}

public Long getId() {
return this.id;
}

public String getNameZh() {
return nameZh;
}

public void setNameZh(String nameZh) {
this.nameZh = nameZh;
}

public String getNameEn() {
return nameEn;
}

public void setNameEn(String nameEn) {
this.nameEn = nameEn;
}

public String getRoleCode() {
return roleCode;
}

public void setRoleCode(String roleCode) {
this.roleCode = roleCode;
}

public String getDescription() {
return this.description;
}

public Set<Resource> getTsResources() {
return this.tsResources;
}

public void setTsResources(Set<Resource> tsResources) {
this.tsResources = tsResources;
}

public Set<User> getTsUsers() {
return this.tsUsers;
}

public void setDescription(String description) {
this.description = description;
}

public void setId(Long id) {
this.id = id;
}

public void setTsUsers(Set<User> tsUsers) {
this.tsUsers = tsUsers;
}

public Boolean getIschecked() {
return ischecked;
}

public void setIschecked(Boolean ischecked) {
this.ischecked = ischecked;
}

}
...全文
198 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
wyfeng0601 2014-09-19
  • 打赏
  • 举报
回复
不好意思,merge也不行,我刚才测试时是因为把,角色用户表:T_USER_ROLE,角色资源表:T_ROLE_RESOURCE两张表数据删除了,没有出现删除语句。
wyfeng0601 2014-09-19
  • 打赏
  • 举报
回复
经过测试使用merge方法可以的,但是什么原因呢,据我所知,merge是hibernate又new的了对象,把要更新的对象拷贝到new的对象里面,执行完成后new的对象是持久状态,而之前的对象还是托管状态。
wyfeng0601 2014-09-19
  • 打赏
  • 举报
回复
是调用的update方法: @Override public <T> T update(T t) { return baseDao.update(t); }
zy_think123 2014-09-19
  • 打赏
  • 举报
回复
使用merge方法试一试
AndyJi123 2014-09-19
  • 打赏
  • 举报
回复
你修改的时候是不是直接用的update()方法?
liguangwen86 2014-09-18
  • 打赏
  • 举报
回复
这个问题很奇怪,没有发现过这个问题,可能需要看源码. 区别应该是这样: (1)scope="prototype"(多态)是在每次用户发起请求时重新生成action对象,对于多线程访问不会出现问题,如果没有配置scope=prototype则添加的时候不会新建一个action,他任然会保留上次访问的过记录的信息。 (2)默认是scope="singleton"(单态),这些bean被spring初始化后,始终只有一份,很适用于无状态的bean,DAO、Service都采用的这种。当然,scope的值还有session,request等等。 (3)希望解决以后附上原因,解决过程中是可以学到很多知识的,特别是看过源码之后就会了解.

67,515

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧