我想用数据库中的一些值填充一个简单的h:datatable标记。但我得到一个例外,我无法找到原因:
java.lang.NumberFormatException:对于输入字符串:“url”
这是我创建数据表的方式:
<h:form>
<h:dataTable value="#{managementBB.retrieveRecords()}" var="record">
<h:column>
<f:facet name="header">URL</f:facet>
#{record.url}
</h:column>
<h:column>
<f:facet name="header">Submition date</f:facet>
#{record.submitionDate}
</h:column>
<h:column>
<f:facet name="header">Unacceptable</f:facet>
#{record.unnaceptableContent}
</h:column>
<h:column>
<f:facet name="header">Option</f:facet>
Something
</h:column>
</h:dataTable>
</h:form>
这是此页面背后的支持bean:
@Named("managementBB")
@SessionScoped
public class ManagementBB implements Serializable{
@EJB
private ILinkManagerEJB linkManagerEJB;
public List<Record> retrieveRecords() {
return linkManagerEJB.retrieveRecords();
}
}
这是访问数据库以获取数据的EJB:
@Stateless(name = "ejbs/LinkManagerEJB")
public class LinkManagerEJB implements ILinkManagerEJB {
@PersistenceContext
private EntityManager entityManager;
public List<Record> retrieveRecords() {
Query allRecords = entityManager.createNamedQuery("allrecordinfo");
return (List<Record>) allRecords.getResultList();
}
}
最后,这是代表数据库中一行的JPA实体:
@Entity
@NamedQueries({@NamedQuery(name = "allrecordinfo",
query = "SELECT r.url, r.submitionDate, r.unnaceptableContent FROM Record r")})
public class Record {
@Id
@GeneratedValue
private long id;
@Column(nullable = false)
private String url;
@Column(nullable = false)
private String submitionDate;
@Column(nullable = false)
private boolean unnaceptableContent;
//Get set methods ...
}
如你所见,它看起来很简单,而且我之前已经这样做了,但现在我很困惑,我不知道为什么不工作。你能帮我找一下我的错误吗?
注意:我非常有信心查询语法正常(我在eclipse的剪贴簿中测试过它)
答案 0 :(得分:3)
java.lang.NumberFormatException:对于输入字符串:“url”
#{record.url}
这表明Record
实际是Object[]
,因为它期待像这样的整数索引
#{record[0]}
事实上,您的查询是错误的,它不会选择Record
,而只会选择单个字段,这些字段会返回List<Object[]>
个字段而不是List<Record>
。演员(会产生警告)不会阻止/改变它。
答案 1 :(得分:2)
查询不正确。
@NamedQueries({ @NamedQuery(name = "allrecordinfo", query = "SELECT r FROM Record r") })
@Entity
public class Record {
}
答案 2 :(得分:1)
为了防止将来出现这样的错误,您应该使用类型化查询而不是强制转换。
从无类型查询中转换查询结果是一种相当古老的做法(实际上是2006年),不再使用了。
一些额外的提示:您不必为EJB指定显式名称。只要@Stateless就足够了。对于CDI bean也是如此,它将获得默认名称。
然后,您可能想重新考虑EJB接口的名称。最初的我最近有点皱眉。
此外,为您从辅助bean返回的数据创建一个getter更为常见。之后,您可以使用值绑定(省略EL演示中的())。
最后,您可能希望将对EJB的调用转移到@PostConstruct方法,因为JSF可能会多次调用您的支持bean的方法,现在每次都会调用DB调用。如果你这样做,你的bean在视图范围内也应该是最好的,但这意味着你要么必须从CDI bean转到常规的JSF托管bean,要么使用seam 3。