这是我考虑此问题的解决方案:
我假设您对JPA(不是Hibernate)感兴趣
我的解决方案不需要扩展任何类,并且应该适用于任何JPA实体bean,它只是您使用的简单类,也不要求实现任何服务或DAO。唯一的要求是转换器直接依赖于JPA库,这可能不是很优雅。
它使用辅助方法对bean的ID进行序列化/反序列化。它仅转换实体bean的id,并将字符串与类名和id进行序列化并转换为base64。由于在jpa中实体的ID 必须实现可序列化的事实,所以这是可能的。该方法的实现在Java 1.7中,但是您可以在那找到Java <1.7的另一种实现。
导入java.io.ByteArrayInputStream;
导入java.io.ByteArrayOutputStream;
导入java.io.IOException;
导入java.io.ObjectInput;
导入java.io.ObjectInputStream;
导入java.io.ObjectOutput;
导入java.io.ObjectOutputStream;
导入javax.faces.bean.ManagedBean;
导入javax.faces.bean.ManagedProperty;
导入javax.faces.bean.RequestScoped;
导入javax.faces.component.UIComponent;
导入javax.faces.context.FacesContext;
导入javax.faces.convert.Converter;
导入javax.faces.convert.ConverterException;
导入javax.persistence.EntityManagerFactory;
/ **
* jsf的jpa实体的通用转换器
*
*使用以下格式将jpa实例转换为字符串:@将字符串转换为按ID搜索的实例
*数据库
*
*这可能是由于jpa需要所有实体ID来
*实现可序列化
*
*要求:-您必须提供名称为“ entityManagerFactory”的实例为
*注入-记住在所有实体中实现equals和hashCode
*班!
*
* /
@ManagedBean
@RequestScoped
公共类EntityConverter实现Converter {
私有静态最终字符CHARACTER_SEPARATOR ='@';
@ManagedProperty(value =“#{entityManagerFactory}”)
私有EntityManagerFactory实体管理器工厂;
公共无效setEntityManagerFactory(EntityManagerFactory实体管理器工厂){
this.entityManagerFactory = entityManagerFactory;
}
私有静态最终字符串为空=“”;
@Override
public Object getAsObject(FacesContext context,UIComponent c,String value){
如果(值== null || value.isEmpty()){
返回null;
}
int索引= value.indexOf(CHARACTER_SEPARATOR);
字符串clazz = value.substring(0,index);
字符串idBase64String = value.substring(index + 1,value.length());
EntityManager entityManager = null;
尝试{
类entityClazz = Class.forName(clazz);
对象ID = convertFromBase64String(idBase64String);
实体管理器=实体管理器工厂.createEntityManager();
对象object = entityManager.find(entityClazz,id);
返回对象
} catch(ClassNotFoundException e){
抛出新的ConverterException(“找不到Jpa实体” + clazz,e);
} catch(IOException e){
抛出新的ConverterException(“无法反序列化jpa类的ID” + clazz,e);
}最后{
if(entityManager!= null){
entityManager.close();
}
}
}
@Override
public String getAsString(FacesContext context,UIComponent c,Object value){
if(value == null){
返回空
}
字符串clazz = value.getClass()。getName();
字符串idBase64String;
尝试{
idBase64String = convertToBase64String(entityManagerFactory.getPersistenceUnitUtil()。getIdentifier(value));
} catch(IOException e){
抛出新的ConverterException(“无法为类” + clazz,e序列化ID);
}
返回clazz + CHARACTER_SEPARATOR + idBase64String;
}
//实用方法,(可以重构为将其移动到另一个地方)
公共静态字符串convertToBase64String(Object o)引发IOException {
返回javax.xml.bind.DatatypeConverter.printBase64Binary(convertToBytes(o));
}
公共静态对象convertFromBase64String(String str)引发IOException,ClassNotFoundException {
返回convertFromBytes(javax.xml.bind.DatatypeConverter.parseBase64Binary(str));
}
公共静态字节[] convertToBytes(Object object)抛出IOException {
尝试(ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutput out = new ObjectOutputStream(bos)){
out.writeObject(object);
返回bos.toByteArray();
}
}
公共静态对象convertFromBytes(byte [] bytes)引发IOException,ClassNotFoundException {
尝试(ByteArrayInputStream bis = new ByteArrayInputStream(bytes; in ObjectInput in = new ObjectInputStream(bis)){
返回in.readObject();
}
}
}
像其他转换器一样使用它