JAXB、Hibernate、延迟加载
我在下面粘贴了一个简单的Hibernate POJO(为了简洁起见,删除了构造函数和setter)。我的问题出现在“用户”关系上。Hibernate lazy可以很好地加载关系,但是当我的CRUD webservice调用(也在下面)封送该对象的一个实例时,它调用关系的“get”方法,从而在Hibernate中引发“No transaction”异常,因为JAXB在会话或事务中都没有访问该关系 POJO:JAXB、Hibernate、延迟加载,hibernate,jaxb,resteasy,Hibernate,Jaxb,Resteasy,我在下面粘贴了一个简单的Hibernate POJO(为了简洁起见,删除了构造函数和setter)。我的问题出现在“用户”关系上。Hibernate lazy可以很好地加载关系,但是当我的CRUD webservice调用(也在下面)封送该对象的一个实例时,它调用关系的“get”方法,从而在Hibernate中引发“No transaction”异常,因为JAXB在会话或事务中都没有访问该关系 POJO: 我没有包含DAO/EJB代码,因为错误发生在Resteasy内部和调用外部,表明问题发生在
我没有包含DAO/EJB代码,因为错误发生在Resteasy内部和调用外部,表明问题发生在编组过程中。我之前也遇到过同样的问题。我假设您在resteasy方法开始时打开了一个hibernate会话和事务,并在方法结束时关闭它。问题是延迟加载会将代理对象返回给用户。您可以单步调试它并运行ls.getUsers()。类型是代理。它只会在您访问该代理中的某个对象后获取实际对象。在您的情况下,这种情况发生在编组期间,但此时,您的会话/事务已关闭,因此出现了错误。如果要在resteasy方法中访问像ls.getUsers.size()这样的对象,那么代理现在将是您期望的实际对象,封送将正常工作,但必须这样做似乎很麻烦。当我遇到问题的时候,我只是决定做一些积极的事情,避免这种混乱。但是,现在,您可以在这里看到一个修复
@Entity
@Table(name = "ldapservers", uniqueConstraints = @UniqueConstraint(columnNames = "hostname"))
@XmlRootElement(name = "ldap-server")
@SuppressWarnings("unused")
public class LdapServer implements Serializable
{
private int ldapServerId;
private String hostname;
private int port;
private Date createDate;
private String createUser;
private Set<User> users = new HashSet<User>(0);
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = "ldapServerID", unique = true, nullable = false)
@XmlAttribute(name="id")
public int getLdapServerId()
{
return this.ldapServerId;
}
@Column(name = "hostname", unique = true, nullable = false)
@XmlElement
public String getHostname()
{
return this.hostname;
}
@Column(name = "port", nullable = false)
@XmlElement
public int getPort()
{
return this.port;
}
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "createDate", nullable = false, length = 19)
@XmlAttribute(name="create-date")
public Date getCreateDate()
{
return this.createDate;
}
@Column(name = "createUser", nullable = false)
@XmlAttribute(name="create-user")
public String getCreateUser()
{
return this.createUser;
}
@OneToMany(fetch = FetchType.LAZY, mappedBy = "ldapServer")
public Set<User> getUsers()
{
return this.users;
}
}
@GET
@Path("/fetch/{id}")
@Produces("application/xml")
public LdapServer getLdapServer(@PathParam("id") int ldapServerID)
{
logger.debug("Fetching LdapServer ID "+ldapServerID);
LdapServer ls = this.home.findById(ldapServerID);
if (ls!=null)
{
logger.debug("Found LdapServer ID "+ldapServerID);
}
else
{
logger.debug("LdapServer ID "+ldapServerID+" not found.");
}
return ls;
}