You should not rely on the first two items in your business logic. The state is mostly replicated asynchronously so your conversational state can get lost. The invalidation of the second level cache is bit more interesting. If JPA entities are changed in one cluster node, a message is asynchronously broadcasted to other nodes, what causes the rejection of the JPA entity from the cache. The replication happens asynchronously again, so you cannot rely on the mechanism to ensure consistency. It only lowers the probability of optimistic locks. Optimistic locking is absolutely needed in distributed (cluster) environments, otherwise the cluster nodes could overwrite the data in the central database. Pessimistic locks are more problematic - and doesn't scale well.

The last item is the most important one. A single point of administration is critical to run clustered environments. You should be able to fire up and kill instances on demand - depending on the load.

So clustering is not necessarily needed for HA. If you would like to run HA applications without a cluster you should consider:

You must not use HTTPSession and Stateful Session Beans as a persistent store. Use them as an optional cache.

Consider optimistic locking as a general strategy early enough. Especially check the presentation logic, whether it can deal with the optimistic lock exceptions.

Use e.g. mod_jk load balancing for spreading evenly the request across the server instances. This is good enough for most applications with a fixed number of nodes.

not even hot-standby. You could have multiple, independent instances and spread the load evenly across them. For stateful components it is essential important to setup "sticky sessions" properly.

For HA production you could maintain a parallel "cluster" which is used for test and upgrade purposes. After a successful upgrade and test, you could switch the load to this cluster and then maintain the "hot" one.