[Persistence, JBoss/CMP, Hibernate, Database] - Modify data within PreUpdate will only merges partially
by Masterozz666
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
18 years, 3 months
[Security & JAAS/JBoss] - Re: How to configure
by draggy
"draggy" wrote : Hello JBoss experts and professionals,
|
| Currently, IÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂâÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂm using JBoss Portal 2.6.4 bundle with Application server 4.2.2 and referring to http://wiki.jboss.org/wiki/NegotiateKerberos about
|
|
| | 3. Modify the ${jboss.server.dir}/conf/jboss-service.xml (if you installed via the JBoss Installer Jar, then the file you need to edit is ${jboss.server.dir}/deploy/security-service.xml) in the server you copied the jars to. You need to change the "jboss.security:service=JaasSecurityManager MBean" to use the new callback handler included with the negotiate jar.
| | You need to find the mbean definition in the file, and add or change the CallbackHandlerClassName? attribute to be the following:
| |
| | <attribute name="CallbackHandlerClassName">org.jboss.web.tomcat.security.AdvancedWebCallbackHandler</attribute>
| |
| | for 4.04 you may need to use ${jboss.server.dir}/deploy/security-service.xml) event it is not installed using the JBoss Installer Jar.
| |
| | for 4.05 you may need to use ${jboss.server.dir}\deploy\security.sar\META-INF\jboss-service.xml
| |
|
| I am not sure how to configure this particular parts:
|
|
| | You need to find the mbean definition in the file, and add or change the CallbackHandlerClassName? attribute to be the following:
| |
| | <attribute name="CallbackHandlerClassName">org.jboss.web.tomcat.security.AdvancedWebCallbackHandler</attribute>
| |
|
| And
|
|
| | for 4.04 you may need to use ${jboss.server.dir}/deploy/security-service.xml) event it is not installed using the JBoss Installer Jar.
| |
| | for 4.05 you may need to use ${jboss.server.dir}\deploy\security.sar\META-INF\jboss-service.xml
| |
|
| However, I have managed to find JAAS in my jboss-service.xml:
|
|
| | <!-- JAAS security manager and realm mapping -->
| | <mbean code="org.jboss.security.plugins.JaasSecurityManagerService"
| | name="jboss.security:service=JaasSecurityManager">
| | <!-- A flag which indicates whether the SecurityAssociation server mode
| | is set on service creation. This is true by default since the
| | SecurityAssociation should be thread local for multi-threaded server
| | operation.
| | -->
| | <attribute name="ServerMode">true</attribute>
| | <attribute name="SecurityManagerClassName">org.jboss.security.plugins.JaasSecurityManager</attribute>
| | <attribute name="DefaultUnauthenticatedPrincipal">anonymous</attribute>
| | <!-- DefaultCacheTimeout: Specifies the default timed cache policy timeout
| | in seconds.
| | If you want to disable caching of security credentials, set this to 0 to
| | force authentication to occur every time. This has no affect if the
| | AuthenticationCacheJndiName has been changed from the default value.
| | -->
| | <attribute name="DefaultCacheTimeout">1800</attribute>
| | <!-- DefaultCacheResolution: Specifies the default timed cache policy
| | resolution in seconds. This controls the interval at which the cache
| | current timestamp is updated and should be less than the DefaultCacheTimeout
| | in order for the timeout to be meaningful. This has no affect if the
| | AuthenticationCacheJndiName has been changed from the default value.
| | -->
| | <attribute name="DefaultCacheResolution">60</attribute>
| | <!-- DeepCopySubjectMode: This set the copy mode of subjects done by the
| | security managers to be deep copies that makes copies of the subject
| | principals and credentials if they are cloneable. It should be set to
| | true if subject include mutable content that can be corrupted when
| | multiple threads have the same identity and cache flushes/logout clearing
| | the subject in one thread results in subject references affecting other
| | threads.
| | -->
| | <attribute name="DeepCopySubjectMode">false</attribute>
| | </mbean>
| |
|
| May I know how to configure it?
|
| Thank you
|
is it just add the
| <attribute name="CallbackHandlerClassName">org.jboss.web.tomcat.security.AdvancedWebCallbackHandler</attribute>
|
just like this:
| <!-- JAAS security manager and realm mapping -->
| <mbean code="org.jboss.security.plugins.JaasSecurityManagerService"
| name="jboss.security:service=JaasSecurityManager">
| <!-- A flag which indicates whether the SecurityAssociation server mode
| is set on service creation. This is true by default since the
| SecurityAssociation should be thread local for multi-threaded server
| operation.
| -->
| <attribute name="ServerMode">true</attribute>
| <attribute name="CallbackHandlerClassName">org.jboss.web.tomcat.security.AdvancedWebCallbackHandler</attribute>
| <attribute name="SecurityManagerClassName">org.jboss.security.plugins.JaasSecurityManager</attribute>
| <attribute name="DefaultUnauthenticatedPrincipal">anonymous</attribute>
| <!-- DefaultCacheTimeout: Specifies the default timed cache policy timeout
| in seconds.
| If you want to disable caching of security credentials, set this to 0 to
| force authentication to occur every time. This has no affect if the
| AuthenticationCacheJndiName has been changed from the default value.
| -->
| <attribute name="DefaultCacheTimeout">1800</attribute>
| <!-- DefaultCacheResolution: Specifies the default timed cache policy
| resolution in seconds. This controls the interval at which the cache
| current timestamp is updated and should be less than the DefaultCacheTimeout
| in order for the timeout to be meaningful. This has no affect if the
| AuthenticationCacheJndiName has been changed from the default value.
| -->
| <attribute name="DefaultCacheResolution">60</attribute>
| <!-- DeepCopySubjectMode: This set the copy mode of subjects done by the
| security managers to be deep copies that makes copies of the subject
| principals and credentials if they are cloneable. It should be set to
| true if subject include mutable content that can be corrupted when
| multiple threads have the same identity and cache flushes/logout clearing
| the subject in one thread results in subject references affecting other
| threads.
| -->
| <attribute name="DeepCopySubjectMode">false</attribute>
| </mbean>
|
is it correct?
Thank you
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4144732#4144732
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4144732
18 years, 3 months