- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
每当我进行连续保存时,我都会收到 TransientObjectException;我在第一次保存或刷新屏幕/页面时没有收到此错误。这让我很困惑,因为一旦对象被成功保存,它就不应该是暂时的,因为它在我的数据库中有一个表示。
我下面的文件(用户和 UserPasswordInfo)具有一对多关系,其中一个用户可以拥有多个 UserPasswordInfo(或 UPI),并且它们由我的用户的主键链接:user_id.
我很确定问题存在于以下文件中,而不是其他地方,因为 TOE 错误仅在添加此文件后出现,据我所知,该软件在其生命周期(几年)中从未出现过此问题.
这是我的 hibernate 文件:
用户.hbm.xml
<hibernate-mapping>
<class name="com.app.common.domain.User" table="users" >
<id name="id" type="java.lang.Integer">
<column name="user_id" />
<generator class="identity" />
</id>
<set name="passwordInfos" table="user_password_info" lazy="false" cascade="all" fetch="select">
<key>
<column name="user_id"></column>
</key>
<one-to-many class="com.app.common.domain.UserPasswordInfo" />
</set>
</class>
</hibernate-mapping>
UserPasswordInfo.hbm.xml
<hibernate-mapping>
<class name="com.app.common.domain.UserPasswordInfo" table="user_password_info">
<id name="passwordInfoId" type="java.lang.Integer">
<column name="password_info_id" />
<generator class="identity" />
</id>
<property name="password" column="password" type="java.lang.String"/>
<property name="passwordTS" column="password_ts" type="java.sql.Timestamp"/>
<property name="pwdChange" column="initial_password_change" type="java.lang.Boolean"/>
<property name="userId" column="user_id" type="java.lang.Integer"/>
</class>
</hibernate-mapping>
这是他们的 Java 文件:
用户.java
import java.sql.Timestamp;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Set;
public class User extends DBObject {//DBObject has a getter and setter for the id
private Set<UserPasswordInfo> passwordInfos = new HashSet<UserPasswordInfo>(0);
public User() {
super();
}
.
.
.
public Set<UserPasswordInfo> getPasswordInfos() {
return passwordInfos;
}
public void setPasswordInfos(Set<UserPasswordInfo> passwordInfos) {
this.passwordInfos = passwordInfos;
}
public void addUPI(String pwd, Timestamp pwdTS, Boolean pwdChng){
UserPasswordInfo upi = new UserPasswordInfo();
upi.setPassword(pwd);
upi.setPasswordTS(pwdTS);
upi.setPwdChange(pwdChng);
if(getId() != null)
upi.setUserId(getId().intValue());
passwordInfos.add(upi);
}
public String getLatestPassword(){
return getSortedList().get(0).getPassword();
}
public UserPasswordInfo getLatestUPI(){
ArrayList<UserPasswordInfo> list = getSortedList();
return (list == null || list.size() == 0) ? null : list.get(0);
}
public ArrayList<String> getLastThreePasswords(){
final ArrayList<UserPasswordInfo> upiList = getSortedList();
if(upiList == null)
return null;
ArrayList<String> list = new ArrayList<String>();
int i = 0;
while(i < 3 && i < list.size()){
list.add(upiList.get(i++).getPassword());
}
return list;
}
public ArrayList<UserPasswordInfo> getSortedList(){
ArrayList<UserPasswordInfo> upi = new ArrayList<UserPasswordInfo>(getPasswordInfos());
if(upi == null || upi.size() == 0){
return null;
}
Collections.sort(upi, new Comparator<UserPasswordInfo>() {
public int compare(UserPasswordInfo o1, UserPasswordInfo o2) {
if (o1.getPasswordTS() == null || o2.getPasswordTS() == null)
return 0;
return o2.getPasswordTS().compareTo(o1.getPasswordTS());
}
});
return upi;
}
}
UserPasswordInfo.java
import java.sql.Timestamp;
public class UserPasswordInfo extends DBObject{
private int passwordInfoId;
private String password;
private Timestamp passwordTS;
private Boolean pwdChange;
private int userId;
public UserPasswordInfo(){}
public UserPasswordInfo(String pwd, Timestamp pwdTS, Boolean pwdChng){
password = pwd;
passwordTS = pwdTS;
pwdChange = pwdChng;
}
public UserPasswordInfo(int userId, String pwd, Timestamp pwdTS, Boolean pwdChng){
this.userId = userId;
password = pwd;
passwordTS = pwdTS;
pwdChange = pwdChng;
}
public int getPasswordInfoId(){
return passwordInfoId;
}
public void setPasswordInfoId(int pid){
passwordInfoId = pid;
}
public String getPassword(){
return password;
}
public void setPassword(String pwd){
password = pwd;
}
public Timestamp getPasswordTS(){
return passwordTS;
}
public void setPasswordTS(Timestamp ts){
passwordTS = ts;
}
public void setPwdChange(Boolean pwdChange) {
this.pwdChange = pwdChange;
}
public Boolean getPwdChange() {
return pwdChange;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
}
这是错误信息:
ERROR BeanPopulator -
propertyName=passwordInfos
readerMethod=public java.util.Set com.app.domain.User.getPasswordInfos()
setterMethod=public void com.app.common.domain.User.setPasswordInfos(java.util.Set)
fromBean=[User someUser, id: 268, role: front desk]
toBean=[User , id: null]
net.sf.gilead.exception.TransientObjectException
at net.sf.gilead.core.hibernate.HibernateUtil.getId(HibernateUtil.java:316)
at net.sf.gilead.core.hibernate.HibernateUtil.getId(HibernateUtil.java:224)
at net.sf.gilead.core.hibernate.HibernateUtil.loadPersistentCollection(HibernateUtil.java:854)
at net.sf.gilead.core.hibernate.HibernateUtil.createPersistentCollection(HibernateUtil.java:843)
at net.sf.gilead.core.beanlib.merge.MergeCollectionReplicator.replicateCollection(MergeCollectionReplicator.java:119)
at net.sf.beanlib.provider.replicator.ReplicatorTemplate.replicate(ReplicatorTemplate.java:112)
at net.sf.beanlib.provider.BeanTransformer.transform(BeanTransformer.java:231)
at net.sf.beanlib.provider.BeanPopulator.doit(BeanPopulator.java:201)
at net.sf.beanlib.provider.BeanPopulator.processSetterMethod(BeanPopulator.java:172)
at net.sf.beanlib.provider.BeanPopulator.populate(BeanPopulator.java:269)
at net.sf.gilead.core.LazyKiller.populate(LazyKiller.java:288)
at net.sf.gilead.core.LazyKiller.attach(LazyKiller.java:237)
at net.sf.gilead.core.PersistentBeanManager.mergePojo(PersistentBeanManager.java:554)
at net.sf.gilead.core.PersistentBeanManager.merge(PersistentBeanManager.java:318)
at net.sf.gilead.core.PersistentBeanManager.mergeCollection(PersistentBeanManager.java:581)
at net.sf.gilead.core.PersistentBeanManager.merge(PersistentBeanManager.java:290)
at net.sf.gilead.gwt.GileadRPCHelper.parseInputParameters(GileadRPCHelper.java:94)
at net.sf.gilead.gwt.GileadRPCHelper.parseInputParameters(GileadRPCHelper.java:137)
at net.sf.gilead.gwt.PersistentRemoteService.processCall(PersistentRemoteService.java:172)
编辑 以下是一些可能与此错误相关的链接和代码部分:
这是我保存对象时调用的方法(上面的错误是在调用这个方法之前抛出的)
@SuppressWarnings({ "rawtypes" })
private List saveObjectList(List<? extends DBObject> values) {
Session session = sessionFactory.getCurrentSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
for (DBObject value : values) {
if (value.getIsDirty()) {
Integer clientId = value.getClientId();
if (value.getId() != null) {//enters here
value = (DBObject) session.merge(value);
session.persist(value);
}
else {
session.save(value);
}
value.setClientId(clientId);
value.setIsDirty(false);
}
}
tx.commit();//fails here
return values;
}
catch (Exception ex) {
String msg = "Failed to save values. ";
if (values == null) {
msg += " Values to save were null.";
}
else {
msg += " Values to save had length: " + values.size();
}
rollbackOrCloseSession(tx, session, "saveObjectList() - " + msg, ex);
return null;
}
}
/**
* Parse RPC input parameters.
* Must be called before GWT service invocation.
* @param rpcRequest the input GWT RPC request
* @param beanManager the Hibernate bean manager
* @param session the HTTP session (for HTTP Pojo store)
*/
public static void parseInputParameters(Object[] parameters,
PersistentBeanManager beanManager,
HttpSession session)
{
// Init classloader for proxy mode
//
if (beanManager.getClassMapper() instanceof ProxyClassMapper)
{
initClassLoader();
}
// Set HTTP session of Pojo store in thread local
//
HttpSessionProxyStore.setHttpSession(session);
// Merge parameters if needed
//
if (parameters != null)
{
long start = System.currentTimeMillis();
for (int index = 0 ; index < parameters.length; index ++)
{
if (parameters[index] != null)
{
try
{
//***ERROR occurs when this is called
parameters[index] = beanManager.merge(parameters[index], true);
}
catch (NotAssignableException ex)
{
log.debug(parameters[index] + " not assignable");
}
catch (TransientObjectException ex)
{
log.info(parameters[index] + " is transient : cannot merge...");
}
}
}
if (log.isDebugEnabled())
{
log.debug("Merge took " + (System.currentTimeMillis() - start) + " ms.");
}
}
}
/**
* Merge the clone POJO to its Hibernate counterpart
*/
public Object merge(Object object) {
// Explicit merge
return merge(object, false);
}
/**
* Merge the clone POJO to its Hibernate counterpart
*/
@SuppressWarnings("unchecked")
public Object merge(Object object, boolean assignable) {
// Precondition checking
//
if (object == null) {
return null;
}
if (_persistenceUtil == null) {
throw new RuntimeException("No Persistence Util set !");
}
// Collection handling
//
if (object instanceof Collection) {
return mergeCollection((Collection) object, assignable);
} else if (object instanceof Map) {
return mergeMap((Map) object, assignable);
} else if (object.getClass().isArray()) {
// Check primitive type
//
if (object.getClass().getComponentType().isPrimitive()) {
return object;
}
// Merge as a collection
//
Object[] array = (Object[]) object;
Collection result = mergeCollection(Arrays.asList(array), assignable);
// Get the result as an array (much more tricky !!!)
//
Class<?> componentType = object.getClass().getComponentType();
Object[] copy = (Object[]) java.lang.reflect.Array.newInstance(componentType, array.length);
return result.toArray(copy);
} else {
return mergePojo(object, assignable);
}
}
/**
* Retrieve the Hibernate Pojo and merge the modification from GWT
*
* @param clonePojo the clone pojo
* @param assignable does the source and target class must be assignable
* @return the merged Hibernate POJO
* @exception UnsupportedOperationException if the clone POJO does not implements ILightEntity and the POJO store is
* stateless
* @exception NotAssignableException if source and target class are not assignable
*/
protected Object mergePojo(Object clonePojo, boolean assignable) {
// Get Hibernate associated class
Class<?> cloneClass = clonePojo.getClass();
Class<?> hibernateClass = null;
if (_classMapper != null) {
hibernateClass = _classMapper.getSourceClass(cloneClass);
}
if (hibernateClass == null) {
// Not a clone : take the inner class
hibernateClass = clonePojo.getClass();
}
// Precondition checking : is the pojo managed by Hibernate
if (_persistenceUtil.isPersistentClass(hibernateClass) == true) {
// Assignation checking
if ((assignable == true) && (hibernateClass.isAssignableFrom(cloneClass) == false)) {
throw new NotAssignableException(hibernateClass, cloneClass);
}
}
// Retrieve the pojo
try {
Serializable id = null;
try {
id = _persistenceUtil.getId(clonePojo, hibernateClass);
if (id == null) {
_log.info("HibernatePOJO not found : can be transient or deleted data : " + clonePojo);
}
} catch (TransientObjectException ex) {
_log.info("Transient object : " + clonePojo);
} catch (NotPersistentObjectException ex) {
if (holdPersistentObject(clonePojo) == false) {
// Do not merge not persistent instance, since they do not
// necessary
// implement the Java bean specification
//
if (_log.isDebugEnabled()) {
_log.debug("Not persistent object, merge is not needed : " + clonePojo);
}
return clonePojo;
} else {
if (_log.isDebugEnabled()) {
_log.debug("Merging wrapper object : " + clonePojo);
}
}
}
if (ClassUtils.immutable(hibernateClass)) {
// Do not clone immutable types
//
return clonePojo;
}
// Create a new POJO instance
//
Object hibernatePojo = null;
try {
if (AnnotationsManager.hasGileadAnnotations(hibernateClass)) {
if (id != null) {
// ServerOnly or ReadOnly annotation : load from DB
// needed
//
hibernatePojo = _persistenceUtil.load(id, hibernateClass);
} else {
// Transient instance
//
hibernatePojo = clonePojo;
}
} else {
Constructor<?> constructor = hibernateClass.getDeclaredConstructor(new Class<?>[] {});
constructor.setAccessible(true);
hibernatePojo = constructor.newInstance();
}
} catch (Exception e) {
throw new RuntimeException("Cannot create a fresh new instance of the class " + hibernateClass, e);
}
// Merge the modification in the Hibernate Pojo
//
_lazyKiller.attach(hibernatePojo, clonePojo);
return hibernatePojo;
} finally {
_persistenceUtil.closeCurrentSession();
_proxyStore.cleanUp();
}
}
@Override
public <T> T populate() {
if (getBeanTransformerSpi() != null) {
getBeanTransformerSpi().getClonedMap().put(fromBean, toBean);
}
// invoking all declaring setter methods of toBean from all matching getter methods of fromBean
for (Method m : baseConfig.getSetterMethodCollector().collect(toBean)) {
processSetterMethod(m);
}
@SuppressWarnings("unchecked")
T ret = (T) toBean;
return ret;
}
private void processSetterMethod(Method setterMethod) {
String methodName = setterMethod.getName();
final String propertyString = methodName.substring(baseConfig.getSetterMethodCollector().getMethodPrefix().length());
if (baseConfig.isDebug()) {
if (log.isInfoEnabled()) {
log.info(new StringBuilder("processSetterMethod: processing propertyString=").append(propertyString).append("")
.append(", fromClass=").append(fromBean.getClass()).append(", toClass=").append(toBean.getClass()).toString());
}
}
Method readerMethod = baseConfig.getReaderMethodFinder().find(propertyString, fromBean);
if (readerMethod == null) {
return;
}
// Reader method of fromBean found
Class<?> paramType = setterMethod.getParameterTypes()[0];
String propertyName = Introspector.decapitalize(propertyString);
try {
doit(setterMethod, readerMethod, paramType, propertyName);
} catch (Exception ex) {
baseConfig.getBeanPopulationExceptionHandler().initFromBean(fromBean).initToBean(toBean).initPropertyName(propertyName)
.initReaderMethod(readerMethod).initSetterMethod(setterMethod).handleException(ex, log);
}
}
private <T> void doit(Method setterMethod, Method readerMethod, Class<T> paramType, final String propertyName) {
if (baseConfig.getDetailedPropertyFilter() != null) {
if (!baseConfig.getDetailedPropertyFilter().propagate(propertyName, fromBean, readerMethod, toBean, setterMethod)) {
return;
}
}
if (baseConfig.getPropertyFilter() != null) {
if (!baseConfig.getPropertyFilter().propagate(propertyName, readerMethod)) {
return;
}
}
Object propertyValue = this.invokeMethodAsPrivileged(fromBean, readerMethod, null);
if (baseConfig.getBeanSourceHandler() != null) {
baseConfig.getBeanSourceHandler().handleBeanSource(fromBean, readerMethod, propertyValue);
}
if (transformer != null) {
PropertyInfo propertyInfo = new PropertyInfo(propertyName, fromBean, toBean);
propertyValue = transformer.transform(propertyValue, paramType, propertyInfo);
}
if (baseConfig.isDebug()) {
if (log.isInfoEnabled()) {
log.info("processSetterMethod: setting propertyName=" + propertyName);
}
}
// Invoke setter method
Object[] args = { propertyValue };
this.invokeMethodAsPrivileged(toBean, setterMethod, args);
return;
}
最佳答案
这可能是由以下代码引起的:
public void addUPI(String pwd, Timestamp pwdTS, Boolean pwdChng){
UserPasswordInfo upi = new UserPasswordInfo();
upi.setPassword(pwd);
upi.setPasswordTS(pwdTS);
upi.setPwdChange(pwdChng);
if(getId() != null)
upi.setUserId(getId().intValue());
passwordInfos.add(upi);
}
如果您调用此方法然后存储您的 User
对象,我会假设抛出异常。关键是您需要先将 UserPasswordInfo
附加到上下文,然后才能将其添加到 User
对象。
所以正确的顺序是先存储UserPasswordInfo:
entityManager.persist(upi);
然后将其添加到密码并存储用户对象:
user.getPasswordInfos().add(upi);
entityManager.save(user);
关于java - 首次保存后出现 TransientObjectException 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44530801/
我尝试根据表单元素的更改禁用/启用保存按钮。但是,当通过弹出按钮选择更改隐藏输入字段值时,保存按钮不受影响。 下面是我的代码。我正在尝试序列化旧的表单值并与更改后的表单值进行比较。但我猜隐藏的字段值无
我正在尝试保存模型的实例,但我得到了 Invalid EmbeddedDocumentField item (1) 其中 1 是项目的 ID(我认为)。 模型定义为 class Graph(Docum
我有一个非常奇怪的问题......在我的 iPhone 应用程序中,用户可以打开相机胶卷中的图像,在我的示例中 1920 x 1080 像素 (72 dpi) 的壁纸。 现在,想要将图像的宽度调整为例
目前,我正在使用具有排序/过滤功能的数据表成功地从我的数据库中显示图像元数据。在我的数据表下方,我使用第三方图像覆盖流( http://www.jacksasylum.eu/ContentFlow/
我的脚本有问题。我想按此顺序执行以下步骤: 1. 保存输入字段中的文本。 2. 删除输入字段中的所有文本。 3. 在输入字段中重新加载之前删除的相同文本。 我的脚本的问题是 ug()- 函数在我的文本
任何人都可以帮助我如何保存多对多关系吗?我有任务,用户可以有很多任务,任务可以有很多用户(多对多),我想要实现的是,在更新表单中,管理员可以将多个用户分配给特定任务。这是通过 html 多选输入来完成
我在 Tensorflow 中训练了一个具有批归一化的模型。我想保存模型并恢复它以供进一步使用。批量归一化是通过 完成的 def batch_norm(input, phase): retur
我遇到了 grails 的问题。我有一个看起来像这样的域: class Book { static belongsTo = Author String toString() { tit
所以我正在开发一个应用程序,一旦用户连接(通过 soundcloud),就会出现以下对象: {userid: userid, username: username, genre: genre, fol
我正在开发一个具有多选项卡布局的 Angular 7 应用程序。每个选项卡都包含一个组件,该组件可以引用其他嵌套组件。 当用户选择一个新的/另一个选项卡时,当前选项卡上显示的组件将被销毁(我不仅仅是隐
我尝试使用 JEditorPane 进行一些简单的文本格式化,但随着知识的增长,我发现 JTextPane 更容易实现并且更强大。 我的问题是如何将 JTextPane 中的格式化文本保存到文件?它应
使用 Docker 相当新。 我为 Oracle 11g Full 提取了一个图像。创建了一个数据库并将应用程序安装到容器中。 正确配置后,我提交了生成 15GB 镜像的容器。 测试了该图像的新容器,
我是使用 Xcode 和 swift 的新手,仍在学习中。我在将核心数据从实体传递到文本字段/标签时遇到问题,然后用户可以选择编辑和保存记录。我的目标是,当用户从 friendslistViewCon
我正在用 Java 编写 Android 游戏,我需要一种可靠的方法来快速保存和加载应用程序状态。这个问题似乎适用于大多数 OO 语言。 了解我需要保存的内容:我正在使用策略模式来控制我的游戏实体。我
我想知道使用 fstream 加载/保存某种结构类型的数组是否是个好主意。注意,我说的是加载/保存到二进制文件。我应该加载/保存独立变量,例如 int、float、boolean 而不是结构吗?我这么
我希望能够将 QNetworkReply 保存到 QString/QByteArray。在我看到的示例中,它们总是将流保存到另一个文件。 目前我的代码看起来像这样,我从主机那里得到一个字符串,我想做的
我正在创建一个绘图应用程序。我有一个带有 Canvas 的自定义 View ,它根据用户输入绘制线条: class Line { float startX, startY, stopX, stop
我有 3 个 Activity 第一个 Activity 调用第二个 Activity ,第二个 Activity 调用第三个 Activity 。 第二个 Activity 使用第一个 Activi
我想知道如何在 Xcode 中保存 cookie。我想使用从一个网页获取的 cookie 并使用它访问另一个网页。我使用下面的代码登录该网站,我想保存从该连接获得的 cookie,以便在我建立另一个连
我有一个 SQLite 数据库存储我的所有日历事件,建模如下: TimerEvent *Attributes -date -dateForMark -reminder *Relat
我是一名优秀的程序员,十分优秀!