Can anybody explain me why I am getting TransientObjectException when I doing merge. Issue is reproducing only when I create RuleTestEntitiy inside constructor of ActivityTestEntity as showed below. It doesn't appears if I do update or create.
Thanks in advance.
Here is a test:
@ContextConfiguration(locations = {
"classpath:testApplicationContext_db.xml"})
public class TransientObjectExceptionTest extends AbstractTestNGSpringContextTests{
@Autowired
SessionFactory sessionFactory;
@Test
public void testAddTestActivity(){
Session session = sessionFactory.openSession();
Transaction tx1 = session.beginTransaction();
ActivityTestEntity newActivityEntity = new ActivityTestEntity();
session.merge(newActivityEntity);
tx1.commit();
session.close();
sessionFactory.close();
}
}
Exception:
org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.xxx.RuleTestEntity
@Entity
@Table(name = "ACTIVITY_TEST")
public class ActivityTestEntity implements Serializable{
private static final long serialVersionUID = 4190826330152288861L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ACTIVITY_ID", nullable = false)
private long id;
@OneToMany(mappedBy = "activity", cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
private Set<RuleTestEntity> rules = new HashSet<>();
public ActivityTestEntity() {
RuleTestEntity rule = new RuleTestEntity();
rule.setActivity(this);
this.getRules().add(rule);
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public Set<RuleTestEntity> getRules() {
return rules;
}
public void setRules(Set<RuleTestEntity> rules) {
this.rules = rules;
}
}
@Entity
@Table(name = "RULE_TEST")
public class RuleTestEntity implements Serializable {
private static final long serialVersionUID = -4208222848601642508L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "RULE_ID", nullable = false)
@XmlElement(name = Identifiable.ID_FIELD_NAME)
private long id;
@ManyToOne
@JoinColumn(name = "ACTIVITY_ID", nullable = true, updatable = false)
@XmlTransient
private ActivityTestEntity activity;
public ActivityTestEntity getActivity() {
return activity;
}
public void setActivity(ActivityTestEntity activity) {
this.activity = activity;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
RuleTestEntity that = (RuleTestEntity) o;
if (id != that.id) {
return false;
}
return activity != null ? activity.equals(that.activity) : that.activity == null;
}
@Override
public int hashCode() {
int result = (int) (id ^ (id >>> 32));
result = 31 * result + (activity != null ? activity.hashCode() : 0);
return result;
}
}