It depends on the web framework you use. Problems occur, when you send entities to another JVM. Two kinds of web frameworks exist:
A) If you use a web framework that loads the whole user interface to the client (e.g GWT), then you have to use DTOs because the client does not understand the bytecode of enhanced entities, but it only understands the pure entity bytecode before JPA has enhanced it. So you cannot send the bytecode of an entity which is enhanced from a JAR-library (Hibernate or JPA jar) to the client (--> ClassNotFoundException). GWT can only send "POJO-bytecode" to the client. GWT maps the bytecode and then the client receives it as HTML / JSON data.
By the way: You can use a framework such as Dozer to create the DTOs.
B) If you use a web framework that is deployed on a server and only sends HTML / JavaScript / JSON responses to the client (e.g.
JSF, Wicket), then you can you the entity. But when a call from the client arrives at the server, you have to merge the detached entity, because it is not anymore in the persistence context.
But also if you use B):
Lazy loading is another problem (LazyInitializationException), so you have to be sure about your loading strategies, when you send entities to the client. DTOs solve this problem.
The following article describes these problems in detail (especially for GWT, but it also applies to other web frameworks):
http://code.google.com/webtoolkit/articles/using_gwt_with_hibernate.html