About Question enthuware.oce-ejbd.v6.2.596 :

Moderator: admin

Post Reply
fjwalraven
Posts: 429
Joined: Tue Jul 24, 2012 2:43 am
Contact:

Re: About Question enthuware.oce-ejbd.v6.2.596 :

Post by fjwalraven »

I think that the following option is a correct option
"Set all non-serializable fields to null."

The reason why it is correct is because the Bean provider may have declared some non-serializable fields as transient. Now in the event that the container doesn't use the Java Serialization, the Bean provider has to make them null in the PostActivate method.
4.2.1 Instance Passivation and Conversational State
While the container is not required to use the Serialization protocol for the Java programming language to store the state of a passivated session instance, it must achieve the equivalent result. The one exception is that containers are not required to reset the value of transient fields during activation
So the Bean provider either makes non-serializable fields null in the PrePassivate method or marks the non-serializable fields as transient and makes them null in the PostActivate method.

Regards,
Frits

admin
Site Admin
Posts: 10055
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.oce-ejbd.v6.2.596 :

Post by admin »

fjwalraven wrote:I think that the following option is a correct option
"Set all non-serializable fields to null."

The reason why it is correct is because the Bean provider may have declared some non-serializable fields as transient. Now in the event that the container doesn't use the Java Serialization, the Bean provider has to make them null in the PostActivate method.
4.2.1 Instance Passivation and Conversational State
While the container is not required to use the Serialization protocol for the Java programming language to store the state of a passivated session instance, it must achieve the equivalent result. The one exception is that containers are not required to reset the value of transient fields during activation
So the Bean provider either makes non-serializable fields null in the PrePassivate method or marks the non-serializable fields as transient and makes them null in the PostActivate method.

Regards,
Frits
Hi Frits,
I not sure I agree with that because PostActivate is meant to be a place where the developer should set a transient field to an appropriate value using the information available from the serializable fields. A transient field may be a computed value and you should use PostActivate to recompute this value. Therefore, setting all transient fields to null is not the right answer.

HTH,
Paul.
If you like our products and services, please help us by posting your review here.

fjwalraven
Posts: 429
Joined: Tue Jul 24, 2012 2:43 am
Contact:

Re: About Question enthuware.oce-ejbd.v6.2.596 :

Post by fjwalraven »

Hi Paul,

Let me try to say it in another way. There are different ways of handling non-serializable fields:
1) Open connections in PostConstruct/PostActivate, and close them in PreDestroy and PrePassivate
2) Set non-serializable fields to null in PrePassivate and create them again in the PostActivate using the information from the other fields.
3) Mark some fields as transient and initialize (make them null) them in the PostActivate

Let me give an example of the third option

In this example I have marked the Connection obtained from the ConnectionFactory as transient as it isn't serializable and it isn't handled by the container (as the @Resource fields are). In my business logic I want to create the Connection object the first time by testing if the object isn't null. This is exactly what I have to take care of in the PostActivate method (as the container doesn't have to use java serialization): set my local connection object to null so that I will create a new (and valid) connection again. Maybe this is not the best example, but what I want to bring about is that this 3rd option might be a good option in some cases.

Code: Select all

@Stateless
@LocalBean
public class WebMessageSender {

	@Resource(lookup = "jms/webmessage")
	ConnectionFactory connfact;

	@Resource(lookup = "jms/websendqueue", name = "q")
	Queue queue;

	@Resource
	SessionContext sc;

	transient private Connection connection;

	public void sendWebMessage(String message) {
		try {
			Connection connection = getCon();
			Session session = connection.createSession(true, 0);
			MessageProducer producer = session.createProducer(queue);
			TextMessage msg = session.createTextMessage(message);
			producer.send(msg);
		} catch (JMSException e) {
			throw new EJBException();
		}

	}

	private Connection getCon() {
		if (connection == null) {
			try {
				this.connection = connfact.createConnection();
			} catch (JMSException e) {
				throw new EJBException();
			}
		}
		return this.connection;
	}


   // lots of other stuff

}
What do you think?

Regards,
Frits

admin
Site Admin
Posts: 10055
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.oce-ejbd.v6.2.596 :

Post by admin »

I understand what you are saying and I agree that the third one is one of the options. But then it is one of the three options. So if you make it the right choice, it would essentially negate the option 2 (of the three you mentioned above).

So what I am saying is, "Set the non-serializable fields to null" is not a rule. It is not a requirement imposed by the specification. It just depends on what that bean is meant to do and that is why it is not a right option.

In other words, if you are asked what "should" you do with non-serializable fields in PostActivate? You answer would be "depends" and not "set them to null".

HTH,
Paul.
If you like our products and services, please help us by posting your review here.

himaiMinh
Posts: 358
Joined: Fri Nov 29, 2013 8:26 pm
Contact:

Re: About Question enthuware.oce-ejbd.v6.2.596 :

Post by himaiMinh »

According to session 4.2.1 ,
The container must be able to properly save and restore the reference to the business interfaces and home and component interfaces of the enterprise bean stored in the instance's state even if the classes that implement the object references are not serializable.
So, does it mean the container must save and restore the objects that are not serializable, such as those reference to SessionContext, EntityManager, EntityManagerFactory and timer ?

admin
Site Admin
Posts: 10055
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.oce-ejbd.v6.2.596 :

Post by admin »

No, this particular statement explicitly lists the objects that it is talking about - business interfaces and home and component interfaces.
But SessionContext, EntityManager, EntityManagerFactory and timer are also restored upon activation.
If you like our products and services, please help us by posting your review here.

himaiMinh
Posts: 358
Joined: Fri Nov 29, 2013 8:26 pm
Contact:

Re: About Question enthuware.oce-ejbd.v6.2.596 :

Post by himaiMinh »

According to the specification, it says
The objects that are assigned to the instance's non-transient fields and the non-transient fields of its interceptors after the PrePassivate method completes must be one of the following;
....
A reference to the EJB's remote interface, even if the stub classes are not serializable,
...
A reference to SessionContext , even if it is not serializable,
A reference to EntityManager, even if it is not serializable,
The container must be able to properly save and restore references to timers... even if the classes that implements the timer are not serializable.
The specification points out "even if it is not serializable". So, how can the container serialize those non-serializable fields?

admin
Site Admin
Posts: 10055
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.oce-ejbd.v6.2.596 :

Post by admin »

This is basic programming stuff.
1. Serialization doesn't necessarily require implementing Serializable. One can use Externalizable also or have a custom serialization mechanism.
2. Restoring doesn't necessarily require serialization. A new object can also be created and initialized.

So basically, it is up to the container how it gets the objects such as EntityManager back to the bean.
If you like our products and services, please help us by posting your review here.

himaiMinh
Posts: 358
Joined: Fri Nov 29, 2013 8:26 pm
Contact:

Re: About Question enthuware.oce-ejbd.v6.2.596 :

Post by himaiMinh »

This may be out of the scope of this question itself.
In session 4.2.1, the container will destroy the stateful bean if the container cannot save and restore the following during @PrePassivate and @PostActivate:
- reference to business interface
- reference to timer
- reference to SessionContext
- reference to JNDI context
- referernce to UserTransaction
- reference to EntityManager or EntityManagerFactory.

How about a reference to an Object that is not in the above category?

If I have a non-serializable and non-transient Object, called BankAccount. If I don't set this BankAccount instance to null during @PrePassivate and set it to a value during @PostActivate, will the container destroy the stateful bean?

admin
Site Admin
Posts: 10055
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.oce-ejbd.v6.2.596 :

Post by admin »

Depends on how the container implements it. Ideally, the bean is not following specification and so the container may throw an exception during prepassivate.
If you like our products and services, please help us by posting your review here.

Post Reply

Who is online

Users browsing this forum: No registered users and 36 guests