My Entities:
@Entity
public class Document {
@Id
protected String id; //It string in purpose
@OneToOne(cascade = ALL)
@JoinColumn(name = "DOCUMENT_DETAILS")
private DocumentDetails details;
}
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "documentDiscr")
@EqualsAndHashCode
public abstract class DocumentDetails {
@Id @GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
private Money total;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "SELLER_ID")
private Company seller;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "BUYER_ID")
private Company buyer;
}
@Entity
public class Company {
@Id
protected String id;
private String name;
private String phoneNumber;
private String email;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "address_id")
private Address address;
}
@Entity
@EqualsAndHashCode
public class Address {
@Id
@GeneratedValue(strategy= GenerationType.SEQUENCE)
private Long id;
private String country;
private String city;
private String postalCode;
private String streetName;
private String streetNumber;
private String apartmentNumber;
}
@Path("path")
@Transactional
public class MyResource {
@Inject
MyRepo myRepo;
@PUT
public Document updateDoc(Document document){
myRepo.update(document);
}
}
public class Repo<T extends MyClass> implements MyRepo<T> {
@PersistenceContext
protected EntityManager entityManager;
public T create(T t) {
t.generateId();
this.entityManager.persist(t);
return t;
}
public T update(T entity) {
return entityManager.merge(entity);
}
}
When I call entityManage.update(documentEntity) and same Company is added as supplier and buyer I see
'Multiple representations of the same entity'
.
I read this but nothing helps. When I removed CascadeType.All I am getting
'detached entity passed to persist: my.pckg.Address'
I also tried to remove CascadeType.Merge but error is the same. What I can do? Where is my mistake?
UPDATE
First I changed @ManyToOne(Cascade.All)
to @ManyToOne()
in DocumentDetails
Second I changed @ManyToOne(Cascade.All)
to @ManyToOne(Cascade.Merge)
in DocumentDetails
.
Third I I changed @ManyToOne(Cascade.All)
to @ManyToOne(all types except all and merge)
in DocumentDetails
.
I also tried same with Address
class
Ok - with hint from Piotr Gwiazda I solved it.
Simple and naive solution is add:
if(seller != null && buyer != null){
if(seller.equals(buyer)){
document.getDetails.setSeller(document.getDetails().getBuyer());
}
}
(better answer is SpringData)
before update()
. This situation has place because when two different objects are equal but they references that are different hibernate can't handle them as same object.
This happens when you overwrite the object with same value but with different hashcode, If i am having employee class and employee is having the address class and if I will save the same employee with same address value but with different hashcode then I will get this issue, If I will clone address and set in employee then Hibernate will get confused and not able to save data
@Entity
@Getter
@Setter
class Person implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="id", unique = true, nullable = false)
private Long id;
@OneToMany(cascade= CascadeType.ALL)
private Set<Address> Addresses = new HashSet<>();
protected Person(){}
}
@Entity
@Getter
@Setter
class Address implements Serializable {
@EmbeddedId
private AddressId addressId;
private State state;
protected Address(){}
}
@Embeddable
@Getter
@Setter
public class AddressId implements Serializable {
@Column(name = "person_id")
private Long personId;
@Column(name = "postcode")
private String postcode;
}
Solution For this
AddressId addressId = new AddressId();
addressId.setPersonId(personId);
addressId.setPostcode("4000"); //person already has an address with this postcode
Address address = null;
for (Address a : person.getAddresses()) {
if (a.getAddressId().equals(addressId)) {
address = a;
break;
}
}
if (address == null) {
address = new Address();
address.setAddressId(addressId);
address.setState(State.ABC); //but I want to change the state from QLD to TAS
person.getAddresses().add(address);
}
else {
address.setState(State.TAS);
}
person = personRepo.save(person);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With