[Tapestry5] tapestry5做一个更新页面使用了选择分类的select组件,分类不变的情况下提交报错

bianweiall 2012-07-27
页面类
ArticleUpdate.java

package com.bw.pages.article;

import java.util.Date;
import java.util.List;

import org.apache.tapestry5.SelectModel;
import org.apache.tapestry5.ValueEncoder;
import org.apache.tapestry5.annotations.Component;
import org.apache.tapestry5.annotations.PageActivationContext;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.corelib.components.Errors;
import org.apache.tapestry5.corelib.components.Select;
import org.apache.tapestry5.corelib.components.TextArea;
import org.apache.tapestry5.corelib.components.TextField;
import org.apache.tapestry5.ioc.annotations.Inject;

import com.bw.entities.Article;
import com.bw.entities.Category;
import com.bw.services.dao.jpa.AppJpaDAO;
import com.bw.util.CategoryEncoder;
import com.bw.util.CategorySelectModel;

public class ArticleUpdate {
	@Property
	private Article article;
	
	@Property
	private Category category;
	
	@Property
	private List<Category> categorys;

	@PageActivationContext
	private int id;

	@Inject
	private AppJpaDAO dao;

	@SuppressWarnings("unused")
	@Component
	private Errors errors;

	@SuppressWarnings("unused")
	@Component(parameters = { "value=article.title" })
	private TextField articleTitle;

	@SuppressWarnings("unused")
	@Component(parameters = { "value=article.content" })
	private TextArea articleContent;
	
	@SuppressWarnings("unused")
	@Component(parameters = { "value=category", "encoder=categoryEncoder",
			"model=categoryModel","blankLabel=${article.category.getTitle()}"})
	private Select categorySelect;

	public SelectModel getCategoryModel() {
		return new CategorySelectModel(categorys);
	}

	@SuppressWarnings("rawtypes")
	public ValueEncoder getCategoryEncoder() {
		return new CategoryEncoder(dao);
	}

	void onPrepare(){
		if (article == null) {
			article = dao.findByID(Article.class, id);
		}
		categorys = dao.findWithJpql("select o from _category o order by o.level asc");
	}
	
	Object onSuccess() {
		String s = new java.text.SimpleDateFormat("yyyy-MM-dd hh:mm:ss")
				.format(new Date());
		article.setCreatedtime(s);
		article.setCategory(category);
		dao.update(article);
		return ArticleList.class;
	}

}



页面模版

ArticleUpdate.tml


<html t:type="layout" title="编辑BLOG"
	xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd" xmlns:p="tapestry:parameter">
	<t:form>
		<p t:id="errors" />
		<p>
			分类:
			<select t:id="categorySelect"></select>
		</p>
		<p>
			标题:
			<input type="text" t:id="articleTitle" />
		</p>
		<p>
			内容:
			<input type="text" t:id="articleContent" />
		</p>
		<p>
			<input type="submit" value="保存" />
		</p>
	</t:form>
</html>



错误提示:


[ERROR] article.ArticleList Render queue error in Expansion[PropBinding[expansion article/List(article.category.getId())]]: Property 'category' (within property expression 'article.category.getId()', of com.bw.pages.article.ArticleList@547f5496) is null.
org.apache.tapestry5.ioc.internal.util.TapestryException: Property 'category' (within property expression 'article.category.getId()', of com.bw.pages.article.ArticleList@547f5496) is null. [at classpath:com/bw/pages/article/ArticleList.tml, line 58]
	at org.apache.tapestry5.internal.bindings.PropBinding.get(PropBinding.java:63)
	at org.apache.tapestry5.internal.structure.ExpansionPageElement.render(ExpansionPageElement.java:45)
	at org.apache.tapestry5.internal.services.RenderQueueImpl.run(RenderQueueImpl.java:72)
	at org.apache.tapestry5.internal.services.PageRenderQueueImpl.render(PageRenderQueueImpl.java:124)
	at $PageRenderQueue_14e66a5d5794.render(Unknown Source)
	at $PageRenderQueue_14e66a5d5793.render(Unknown Source)
	at org.apache.tapestry5.internal.services.MarkupRendererTerminator.renderMarkup(MarkupRendererTerminator.java:37)
	at org.apache.tapestry5.services.TapestryModule$30.renderMarkup(TapestryModule.java:1980)
	at $MarkupRenderer_14e66a5d5797.renderMarkup(Unknown Source)
bianweiall 2012-07-27
JAP关系映射相关

Article.java
package com.bw.entities;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;

@Entity(name = "_article")
@SequenceGenerator(name = "article_id_seq", sequenceName = "article_id_seq")
public class Article {

	@Id
	@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "article_id_seq")
	private int id;
	private String title;

	@ManyToOne(cascade = { CascadeType.MERGE, CascadeType.REFRESH })
	@JoinColumn(name = "categoryid")
	private Category category;

	// @Lob 不知道为什么用这个就乱码!
	@Column(length = 8000)
	private String content;
	private String createdtime;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public String getCreatedtime() {
		return createdtime;
	}

	public void setCreatedtime(String createdtime) {
		this.createdtime = createdtime;
	}

	public Category getCategory() {
		return category;
	}

	public void setCategory(Category category) {
		this.category = category;
	}

}



Category.java
package com.bw.entities;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;

@Entity(name = "_category")
@SequenceGenerator(name = "seq_id_category", sequenceName = "seq_id_category")
public class Category {

	@Id
	@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_id_category")
	private int id;
	private String title;
	private int level;
	
	@OneToMany(mappedBy="category",cascade=CascadeType.ALL,fetch=FetchType.LAZY)
	private Set<Article> articles = new HashSet<Article>();

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public int getLevel() {
		return level;
	}

	public void setLevel(int level) {
		this.level = level;
	}

	public Set<Article> getArticles() {
		return articles;
	}

	public void setArticles(Set<Article> articles) {
		this.articles = articles;
	}

}

bianweiall 2012-07-27
自定义select组件相关

CategoryOptionModel.java

package com.bw.util;

import java.util.Map;

import org.apache.tapestry5.OptionModel;

import com.bw.entities.Category;

public class CategoryOptionModel implements OptionModel {

	private Category category;

	public CategoryOptionModel(Category category) {
		this.category = category;
	}

	public String getLabel() {
		return category.getTitle();
	}

	public boolean isDisabled() {
		// TODO Auto-generated method stub
		return false;
	}

	public Map<String, String> getAttributes() {
		// TODO Auto-generated method stub
		return null;
	}

	public Object getValue() {
		return category;
	}

}



CategorySelectModel.java
package com.bw.util;

import java.util.ArrayList;
import java.util.List;

import org.apache.tapestry5.OptionGroupModel;
import org.apache.tapestry5.OptionModel;
import org.apache.tapestry5.util.AbstractSelectModel;

import com.bw.entities.Category;

public class CategorySelectModel extends AbstractSelectModel {

	private List<Category> categorys;

	public CategorySelectModel(List<Category> categorys) {
		this.categorys = categorys;
	}

	public List<OptionGroupModel> getOptionGroups() {
		// TODO Auto-generated method stub
		return null;
	}

	public List<OptionModel> getOptions() {
		List<OptionModel> list = new ArrayList<OptionModel>();
		for (Category c : categorys) {
			list.add(new CategoryOptionModel(c));
		}
		return list;
	}

}



CategoryEncoder.java
package com.bw.util;

import org.apache.tapestry5.ValueEncoder;

import com.bw.entities.Category;
import com.bw.services.dao.jpa.AppJpaDAO;

@SuppressWarnings("rawtypes")
public class CategoryEncoder implements ValueEncoder {

	private AppJpaDAO source;

	public CategoryEncoder(AppJpaDAO source) {
		this.source = source;
	}

	public String toClient(Object obj) {
		return "" + ((Category) obj).getId();
	}

	public Object toValue(String str) {
		return source.findByID(Category.class, Integer.parseInt(str));
	}

}

bianweiall 2012-07-27
自学的java,代码有问题不要笑话了,也只能摸索成这样了,错误的地方希望指点一下!
seris 2012-07-27
category为空的时候处理下,blankLabel=${article.category.getTitle()}这种的最好用blankLabel=${article?.category?.getTitle()}
tapestry 2012-08-03
    void setupRender(){ 
        if (article == null) { 
            article = dao.findByID(Article.class, id); 
        }
    }
bianweiall 2012-08-06
问过群里的兄弟了,最后是这样解决的
Object onSuccess() { 
        String s = new java.text.SimpleDateFormat("yyyy-MM-dd hh:mm:ss") 
                .format(new Date()); 
        article.setCreatedtime(s); 
        if (category == null) { 
            category=category; 
        }
        article.setCategory(category); 
        dao.update(article); 
        return ArticleList.class; 
    }
Global site tag (gtag.js) - Google Analytics