[jboss-user] [Persistence, JBoss/CMP, Hibernate, Database] - Modify data within PreUpdate will only merges partially
Masterozz666
do-not-reply at jboss.com
Thu Apr 17 03:33:35 EDT 2008
Hi,
i have a problem with entity listeners using @PreUpdate to modify the data.
There are two entity beans, the first contains a collection of the second entity bean => OneToMany-Mapping. Something like that:
| @Entity
| @Table(name = "TEST_FIRSTBEAN")
| public class FirstBean implements Serializable {
|
| private static final long serialVersionUID = 8150999009636714523L;
|
| private Integer id;
| private Integer state;
| private Set<SecondBean> secondBeans = new HashSet<SecondBean>(0);
|
| public FirstBean() {
| }
|
| @Id
| @GeneratedValue(strategy = GenerationType.AUTO)
| @Column(name = "ID", unique = true, nullable = false, precision = 22, scale = 0)
| public Integer getId() {
| return this.id;
| }
|
| public void setId(Integer id) {
| this.id = id;
| }
|
| @Column(name = "STATE")
| public Integer getState() {
| return this.state;
| }
|
| public void setState(Integer state) {
| this.state = state;
| }
|
| @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "firstBean")
| public Set<SecondBean> getSecondBeans() {
| return this.secondBeans;
| }
|
| public void setSecondBeans(Set<SecondBean> bBeans) {
| this.secondBeans = bBeans;
| }
|
| }
|
and
| @Entity
| @Table(name = "TEST_SECONDBEAN")
| public class SecondBean implements Serializable {
| private static final long serialVersionUID = -5353954801248924436L;
|
| private Integer id;
| private Integer state;
| private FirstBean firstBean;
|
| public SecondBean() {
| }
|
| @Id
| @GeneratedValue(strategy = GenerationType.AUTO)
| @Column(name = "ID", unique = true, nullable = false, precision = 22, scale = 0)
| public Integer getId() {
| return this.id;
| }
|
| public void setId(Integer id) {
| this.id = id;
| }
|
| @Column(name = "STATE")
| public Integer getState() {
| return this.state;
| }
|
| public void setState(Integer state) {
| this.state = state;
| }
|
| @ManyToOne(fetch = FetchType.EAGER)
| @JoinColumn(name = "FIRSTBEAN_ID")
| public FirstBean getFirstBean() {
| return this.firstBean;
| }
|
| public void setFirstBean(FirstBean firstBean) {
| this.firstBean = firstBean;
| }
|
| }
|
There is also a simple entity listener. In the PreUpdate-Method It will set the state of the second beans, if the state of the first bean was set. Something like this:
| public class FirstBeanEntityListener {
| private static final Logger LOGGER = Logger.getLogger(FirstBeanEntityListener.class);
|
| public FirstBeanEntityListener() {
| super();
| }
|
| @PreUpdate
| public void preUpdate(final FirstBean bean) throws NamingException {
| LOGGER.info("* FirstBean '"+bean.getName()+"' entity listener: @preUpdate called");
|
| if (bean != null && bean.getState() != null) {
| LOGGER.info(" FirstBean '"+bean.getName()+"': state set");
|
| for (SecondBean childBeans : bean.getSecondBeans()) {
| LOGGER.info(" set state for second bean: " + childBeans.getName());
| childBeans.setState(new Integer(1));
| }
| }
| }
|
| }
|
The entity listener is bound to the entity bean using orm.xml:
<?xml version="1.0" encoding="UTF-8"?>
| <entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
| xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd" version="1.0">
| <entity class="FirstBean">
| <entity-listeners>
| <entity-listener class="FirstBeanEntityListener" />
| </entity-listeners>
| </entity>
| </entity-mappings>
The problem is now: If i have one FirstBean with any number of second beans, and i set the state of the first bean on client side, merge it in a stateless session bean and look at the database after that, state of one SecondBean wasn't set, but all others are set. Assume a jUnit test like that:
public class EntityBeanListenerTest {
|
| private TestServiceRemote testRemoteBean = null;
|
| @Before
| public void setUp() throws NamingException, RemoteCheckedException {
| //Perform lookup:
| ...
| this.testRemoteBean = (TestServiceRemote) ctx.lookup("TestService");
| }
|
| @After
| public void tearDown() throws Exception {
| this.testRemoteBean = null;
| }
|
| private FirstBean createSampleFirstBean() {
| final FirstBean firstBean;
| final SecondBean secondBean1;
| final SecondBean secondBean2;
| final SecondBean secondBean3;
|
| //Init first bean
| firstBean = new FirstBean();
|
| //Init second beans
| secondBean1 = new SecondBean();
| secondBean2 = new SecondBean();
| secondBean3 = new SecondBean();
|
| //Add second beans to first bean
| firstBean.getSecondBeans().add(secondBean1);
| firstBean.getSecondBeans().add(secondBean2);
| firstBean.getSecondBeans().add(secondBean3);
|
| secondBean1.setFirstBean(firstBean);
| secondBean2.setFirstBean(firstBean);
| secondBean3.setFirstBean(firstBean);
|
| return firstBean;
| }
|
| @Test
| public void testFirstBeanDeletion() throws RemoteCheckedException {
| FirstBean firstBean;
|
| //Reset database, will only clean table data
| this.testRemoteBean.resetDatabase();
|
| //Create data
| firstBean = this.createSampleFirstBean();
|
| //Save data and retrieve persisted data
| this.testRemoteBean.persistFirstBean(firstBean);
| firstBean = this.testRemoteBean.getFirstBean();
|
| firstBean.setState(new Integer(1));
| this.testRemoteBean.mergeFirstBean(firstBean);
| firstBean = this.testRemoteBean.getFirstBean();
|
| for (final SecondBean secondBean : firstBean.getSecondBeans()) {
| //This will fail on one bean, which one is indeterministic
| Assert.assertNotNull("Second beans have not been deleted", secondBean.getState());
| }
| }
|
| }
I though the listeners should set all states of second beans, but for one second bean, the state wasn't set.
If i perform a flush after merging the data in the same transaction in the session bean, the jUnit test will pass.
Can anyone explain, why this happens? Am i doing something wrong? Must i always perform a flush?
I am using JBoss AS 4.2.2 GA.
Thanks in advance,
Markus
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4144737#4144737
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4144737
More information about the jboss-user
mailing list