[CONF] Apache Tapestry Persistent Page Data

2011-07-15 Thread confluence







Persistent Page Data
Page edited by DEMEY Emmanuel


 Changes (2)
 




...
 {code:title=Example: Flash Strategy} 
@Persist(flash) @Persist(PersistenceConstants.FLASH) 
  private into value; {code} 
...
 {code:title=Example: Client Strategy} 
@Persist(client) @Persist(PersistenceConstants.CLIENT) 
  private into value; {code} 
...


Full Content


Related Articles


 Page:
 Persistent Page Data





 Page:
 Session Storage




 

Persistent Page Data

The use of the term "persistence" here refers to page-level persistence, NOT database persistence.

Most instance variables in Tapestry are automatically cleared at the end of each request. This is important, as it pertains to how Tapestry pages are shared, over time, by many users.

However, you often want to store some data on a single page, and have access to it in later requests to that same page, without having to store it in a database between requests.  (To store values across multiple pages, see Session Storage.)

Making page data persist across requests to a single page is accomplished with the @Persist annotation. This annotation is applied to private instance fields of components:



  @Persist
  private int value;



Such annotated fields will retain their state between requests. Generally, speaking, this means that the value is stored into the session (but other approaches are possible).

Whenever you make a change to a persistent field, its value is saved. On later requests to the same page, the value for the field is restored.

Persistence Strategies

The value for each field is the strategy used to store the field between requests.

Session Strategy

The session strategy stores field changes into the session; the session is created as necessary.

A suitably long session attribute name is used; it incorporates the name of the page, the nested component id, and the name of the field.

Session strategy is the default strategy used unless otherwise overridden.

Example: Session Strategy

  @Persist
  private into value;



Flash Strategy

The flash strategy stores information in the session as well, just for not very long. Values are stored into the session, but then deleted from the session as they are first used to restore a page's state.

The flash is typically used to store temporary messages that should only be displayed to the user once.

Example: Flash Strategy

  @Persist(PersistenceConstants.FLASH)
  private into value;



Client Strategy

The field is persisted onto the client; you will see an additional query parameter in each URL (or an extra hidden field in each form).

Client persistence is somewhat expensive. It can bloat the size of the rendered pages by adding hundreds of characters to each link. There is extra processing on each request to de-serialize the values encoded into the query parameter.

Client persistence does not scale very well; as more information is stored into the query parameter, its length can become problematic. In many cases, web browsers, firewalls or other servers may silently truncate the URL which will break the application.

Use client persistence with care, and store a minimal amount of data. Try to store the identity (that is, primary key) of an object, rather than the object itself.

Example: Client Strategy

  @Persist(PersistenceConstants.CLIENT)
  private into value;



Persistence Strategy Inheritance

By default the value for the Persist annotation is the empty string. When this is true, then the actual strategy to be used is determined by a search up the component hierarchy.

For each component, the meta-data property tapestry.persistence-strategy is checked. This can be specified using the Meta annotation.

If the value is non-blank, then that strategy is used. This allows a component to control the persistence strategy used inside any sub-components (that don't explicitly use a different strategy).

In any case, if no component provides the meta data, then the ultimate default, "session", is used.

Default Values

Fields marked with @Persist may not have default values (whether set inline, or inside a constructor).

Clearing Persistent Fields

If you reach a point where you know that all data for a page can be discarded, you can do exactly that.

The method discardPersistentFieldChanges() of ComponentResources will discard all persistent fields for the page, regardless of which 

[jira] [Commented] (TAP5-1576) JPA Integration 5.3.0 with Primary Key Entity Classes Fails

2011-07-15 Thread Igor Drobiazko (JIRA)

[ 
https://issues.apache.org/jira/browse/TAP5-1576?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13066115#comment-13066115
 ] 

Igor Drobiazko commented on TAP5-1576:
--

Lenny, can you please provide the persistence unit configuration? I can't 
reproduce the issue in my tests.

 JPA Integration 5.3.0 with Primary Key Entity Classes Fails
 ---

 Key: TAP5-1576
 URL: https://issues.apache.org/jira/browse/TAP5-1576
 Project: Tapestry 5
  Issue Type: Bug
  Components: tapestry-jpa
Affects Versions: 5.3, 5.4
Reporter: Lenny Primak
Assignee: Igor Drobiazko

 Single Persistence Unit this time, Glassfish 3,1
 This used to work with Tynamo JPA as well.
 Everything works until I introduce a primary key entity reference such as 
 this:
 Thanks!
 --- Main Entity --
 /**
 *
 * @author lprimak
 */
 @Entity
 @Table(name = webstats)
 @XmlRootElement
 @NamedQueries(
 {
 ...
 })
 @Data
 public class WebStats implements Serializable
 {
public String getDate()
{
return webStatsPK.getSdate();
}
public String getStatisticName()
{
return webStatsPK.getSName();
}
private static final long serialVersionUID = 1L;
@EmbeddedId
protected WebStatsPK webStatsPK;
@Basic(optional = false)
@NotNull
@Column(name = nvisit)
private long nvisit;
@Column(name = ncarrier)
private Long ncarrier;
@Column(name = ntrack)
private Long ntrack;
@Column(name = nadmin)
private Long nadmin;
@Column(name = nother)
private Long nother;
public WebStats()
{
}
public WebStats(WebStatsPK webstatsPK)
{
this.webStatsPK = webstatsPK;
}
public WebStats(WebStatsPK webstatsPK, long nvisit)
{
this.webStatsPK = webstatsPK;
this.nvisit = nvisit;
}
public WebStats(String sdate, String sName)
{
this.webStatsPK = new WebStatsPK(sdate, sName);
}
 }
 - Embedded Primary Key ---
 /**
 *
 * @author lprimak
 */
 @Embeddable
 @Data
 public class WebStatsPK implements Serializable
 {
/**
 * 
 */
private static final long serialVersionUID = 1L;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 8)
@Column(name = sdate)
private String sdate;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 50)
@Column(name = sName)
private String sName;
public WebStatsPK()
{
}
public WebStatsPK(String sdate, String sName)
{
this.sdate = sdate;
this.sName = sName;
}
 }
 
 Here is the error:
 SEVERE: Error invoking service contribution method 
 org.apache.tapestry5.jpa.JpaModule.provideValueEncoders(MappedConfiguration, 
 boolean, EntityManagerSource, EntityManagerManager, TypeCoercer, 
 PropertyAccess, LoggerSource): The type [null] is not the expected 
 [EntityType] for the key class [class 
 com.flowlogix.website.entities.WebStatsPK].
 SEVERE: Operations trace:
 SEVERE: [ 1] Constructing instance of page class 
 org.apache.tapestry5.corelib.pages.ExceptionReport
 SEVERE: [ 2] Realizing service ValueEncoderSource
 SEVERE: [ 3] Invoking 
 org.apache.tapestry5.services.TapestryModule.buildValueEncoderSource(Map, 
 InvalidationEventHub) (at TapestryModule.java:2337)
 SEVERE: [ 4] Invoking 
 org.apache.tapestry5.services.TapestryModule.buildValueEncoderSource(Map, 
 InvalidationEventHub) (at TapestryModule.java:2337)
 SEVERE: [ 5] Determining injection value for parameter #1 (java.util.Map)
 SEVERE: [ 6] Collecting mapped configuration for service ValueEncoderSource
 SEVERE: [ 7] Invoking method 
 org.apache.tapestry5.jpa.JpaModule.provideValueEncoders(MappedConfiguration, 
 boolean, EntityManagerSource, EntityManagerManager, TypeCoercer, 
 PropertyAccess, LoggerSource) (at JpaModule.java:180).
 SEVERE: Construction of service ValueEncoderSource failed: Error invoking 
 service builder method 
 org.apache.tapestry5.services.TapestryModule.buildValueEncoderSource(Map, 
 InvalidationEventHub) (at TapestryModule.java:2337) (for service 
 'ValueEncoderSource'): Error invoking service contribution method 
 org.apache.tapestry5.jpa.JpaModule.provideValueEncoders(MappedConfiguration, 
 boolean, EntityManagerSource, EntityManagerManager, TypeCoercer, 
 PropertyAccess, LoggerSource): The type [null] is not the expected 
 [EntityType] for the key class [class 
 com.flowlogix.website.entities.WebStatsPK].
 java.lang.RuntimeException: Error invoking service builder method 
 org.apache.tapestry5.services.TapestryModule.buildValueEncoderSource(Map, 
 InvalidationEventHub) (at TapestryModule.java:2337) (for service 
 'ValueEncoderSource'): Error invoking service contribution method 
 

[jira] [Commented] (TAP5-1576) JPA Integration 5.3.0 with Primary Key Entity Classes Fails

2011-07-15 Thread Lenny Primak (JIRA)

[ 
https://issues.apache.org/jira/browse/TAP5-1576?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanelfocusedCommentId=13066146#comment-13066146
 ] 

Lenny Primak commented on TAP5-1576:


 1 ?xml version=1.0 encoding=UTF-8?
 2 persistence version=2.0 
xmlns=http://java.sun.com/xml/ns/persistence; 
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance; 
xsi:schemaLocation=http://java.sun.com/xml/ns/persistence 
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd;
 3   persistence-unit name=Hope transaction-type=JTA
 4 jta-data-sourcejdbc/Billing/jta-data-source
 5 exclude-unlisted-classesfalse/exclude-unlisted-classes
 6 properties/
 7   /persistence-unit
 8 /persistence


 JPA Integration 5.3.0 with Primary Key Entity Classes Fails
 ---

 Key: TAP5-1576
 URL: https://issues.apache.org/jira/browse/TAP5-1576
 Project: Tapestry 5
  Issue Type: Bug
  Components: tapestry-jpa
Affects Versions: 5.3, 5.4
Reporter: Lenny Primak
Assignee: Igor Drobiazko

 Single Persistence Unit this time, Glassfish 3,1
 This used to work with Tynamo JPA as well.
 Everything works until I introduce a primary key entity reference such as 
 this:
 Thanks!
 --- Main Entity --
 /**
 *
 * @author lprimak
 */
 @Entity
 @Table(name = webstats)
 @XmlRootElement
 @NamedQueries(
 {
 ...
 })
 @Data
 public class WebStats implements Serializable
 {
public String getDate()
{
return webStatsPK.getSdate();
}
public String getStatisticName()
{
return webStatsPK.getSName();
}
private static final long serialVersionUID = 1L;
@EmbeddedId
protected WebStatsPK webStatsPK;
@Basic(optional = false)
@NotNull
@Column(name = nvisit)
private long nvisit;
@Column(name = ncarrier)
private Long ncarrier;
@Column(name = ntrack)
private Long ntrack;
@Column(name = nadmin)
private Long nadmin;
@Column(name = nother)
private Long nother;
public WebStats()
{
}
public WebStats(WebStatsPK webstatsPK)
{
this.webStatsPK = webstatsPK;
}
public WebStats(WebStatsPK webstatsPK, long nvisit)
{
this.webStatsPK = webstatsPK;
this.nvisit = nvisit;
}
public WebStats(String sdate, String sName)
{
this.webStatsPK = new WebStatsPK(sdate, sName);
}
 }
 - Embedded Primary Key ---
 /**
 *
 * @author lprimak
 */
 @Embeddable
 @Data
 public class WebStatsPK implements Serializable
 {
/**
 * 
 */
private static final long serialVersionUID = 1L;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 8)
@Column(name = sdate)
private String sdate;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 50)
@Column(name = sName)
private String sName;
public WebStatsPK()
{
}
public WebStatsPK(String sdate, String sName)
{
this.sdate = sdate;
this.sName = sName;
}
 }
 
 Here is the error:
 SEVERE: Error invoking service contribution method 
 org.apache.tapestry5.jpa.JpaModule.provideValueEncoders(MappedConfiguration, 
 boolean, EntityManagerSource, EntityManagerManager, TypeCoercer, 
 PropertyAccess, LoggerSource): The type [null] is not the expected 
 [EntityType] for the key class [class 
 com.flowlogix.website.entities.WebStatsPK].
 SEVERE: Operations trace:
 SEVERE: [ 1] Constructing instance of page class 
 org.apache.tapestry5.corelib.pages.ExceptionReport
 SEVERE: [ 2] Realizing service ValueEncoderSource
 SEVERE: [ 3] Invoking 
 org.apache.tapestry5.services.TapestryModule.buildValueEncoderSource(Map, 
 InvalidationEventHub) (at TapestryModule.java:2337)
 SEVERE: [ 4] Invoking 
 org.apache.tapestry5.services.TapestryModule.buildValueEncoderSource(Map, 
 InvalidationEventHub) (at TapestryModule.java:2337)
 SEVERE: [ 5] Determining injection value for parameter #1 (java.util.Map)
 SEVERE: [ 6] Collecting mapped configuration for service ValueEncoderSource
 SEVERE: [ 7] Invoking method 
 org.apache.tapestry5.jpa.JpaModule.provideValueEncoders(MappedConfiguration, 
 boolean, EntityManagerSource, EntityManagerManager, TypeCoercer, 
 PropertyAccess, LoggerSource) (at JpaModule.java:180).
 SEVERE: Construction of service ValueEncoderSource failed: Error invoking 
 service builder method 
 org.apache.tapestry5.services.TapestryModule.buildValueEncoderSource(Map, 
 InvalidationEventHub) (at TapestryModule.java:2337) (for service 
 'ValueEncoderSource'): Error invoking service contribution method 
 org.apache.tapestry5.jpa.JpaModule.provideValueEncoders(MappedConfiguration, 
 boolean, EntityManagerSource, EntityManagerManager, TypeCoercer,