Мы хотели бы использовать функциональность управления связями Hibernate (5.4.2.Final) вместе с улучшением байт-кода и полевым доступом. Это работает для некоторых случаев, а не для других за пределами нашего понимания - будем признательны за помощь / руководство.
Мы разобрали случай, как показано ниже, но (старые, возможно, ненужные) аннотации сохранены.
В простейшем случае есть два типа сущностей: «Foo» и «Link». «Ссылка» - это простая направленная связь между двумя сущностями Foo. У Foo есть два свойства коллекции, которые отражают это отношение - входящее и исходящее. Мы начинаем с базы данных, имеющей только один экземпляр Foo с идентификатором 1. Затем мы пытаемся в одной транзакции создать еще один (свежий) Foo (id = 2) и ссылку из Foo # 1 (загружен) на Foo # 2 (свежий). Мы устанавливаем свойства ссылки «от» и «до» и желаем / ожидаем, что управление расширением / связыванием байт-кода обновит «другие стороны» этих отношений. Что происходит, так это то, что freshLink.setTo () отражается в свойстве freshFoo.incoming, а freshLink.setFrom () НЕ отражается в свойствеloadedFoo.outgoing.
Может кто-нибудь помочь нам понять, почему? Что мы делаем неправильно или ожидаем того, чего не должны?
Основной код:
final Foo loadedFoo = session.get(Foo.class, 1L);
final Foo freshFoo = new Foo();
freshFoo.setId(2L);
final Link freshLink = new Link();
freshLink.setId(1L);
freshLink.setTo(freshFoo);
System.out.println("Other side of 'to' (in freshFoo) updated: " + freshFoo.getIncoming().contains(freshLink));
freshLink.setFrom(loadedFoo);
System.out.println("Other side of 'from' (in loadedFoo) updated: " + loadedFoo.getOutgoing().contains(freshLink) );
session.save(freshFoo);
session.save(freshLink);
session.saveOrUpdate(loadedFoo);
Код Foo:
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@javax.persistence.Entity
@Table(name = "foo")
@org.hibernate.annotations.BatchSize(size = 10)
@org.hibernate.annotations.DynamicInsert(false)
@org.hibernate.annotations.DynamicUpdate(false)
@org.hibernate.annotations.SelectBeforeUpdate(false)
@org.hibernate.annotations.Proxy(lazy = false)
@org.hibernate.annotations.Polymorphism(type = org.hibernate.annotations.PolymorphismType.IMPLICIT)
@org.hibernate.annotations.Cache(include = "all", usage = org.hibernate.annotations.CacheConcurrencyStrategy.READ_WRITE)
@javax.persistence.Access(javax.persistence.AccessType.FIELD)
public class Foo {
@Id
@Column(name = "id", nullable = false, updatable = false)
@org.hibernate.annotations.Type(type = "long")
private Long id = null;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "to")
@org.hibernate.annotations.LazyCollection(org.hibernate.annotations.LazyCollectionOption.EXTRA)
@org.hibernate.annotations.OptimisticLock(excluded = false)
@org.hibernate.annotations.Fetch(org.hibernate.annotations.FetchMode.SUBSELECT)
@org.hibernate.annotations.NotFound(action = org.hibernate.annotations.NotFoundAction.EXCEPTION)
private Set<Link> incoming = new HashSet<>();
@OneToMany(fetch = FetchType.LAZY, mappedBy = "from")
@org.hibernate.annotations.LazyCollection(org.hibernate.annotations.LazyCollectionOption.EXTRA)
@org.hibernate.annotations.OptimisticLock(excluded = false)
@org.hibernate.annotations.Fetch(org.hibernate.annotations.FetchMode.SUBSELECT)
@org.hibernate.annotations.NotFound(action = org.hibernate.annotations.NotFoundAction.EXCEPTION)
private Set<Link> outgoing = new HashSet<>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Set<Link> getIncoming() {
return incoming;
}
public Set<Link> getOutgoing() {
return outgoing;
}
public void addIncoming(Link link) {
this.incoming.add(link);
}
public void addOutgoing(Link link) {
this.outgoing.add(link);
}
}
Код ссылки:
import javax.persistence.Column;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@javax.persistence.Entity
@Table(name = "link")
@org.hibernate.annotations.BatchSize(size = 100)
@org.hibernate.annotations.DynamicInsert(false)
@org.hibernate.annotations.DynamicUpdate(false)
@org.hibernate.annotations.SelectBeforeUpdate(false)
@org.hibernate.annotations.Proxy(lazy = false)
@org.hibernate.annotations.Polymorphism(type = org.hibernate.annotations.PolymorphismType.IMPLICIT)
@org.hibernate.annotations.Cache(include = "all", usage = org.hibernate.annotations.CacheConcurrencyStrategy.READ_WRITE)
@javax.persistence.Access(javax.persistence.AccessType.FIELD)
public class Link {
@Id
@Column(name = "id", nullable = false, updatable = false)
@org.hibernate.annotations.Type(type = "long")
private Long id = null;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "from_id", nullable = false)
@org.hibernate.annotations.LazyToOne(org.hibernate.annotations.LazyToOneOption.NO_PROXY)
@org.hibernate.annotations.OptimisticLock(excluded = false)
@org.hibernate.annotations.Fetch(org.hibernate.annotations.FetchMode.SELECT)
@org.hibernate.annotations.NotFound(action = org.hibernate.annotations.NotFoundAction.EXCEPTION)
private Foo from;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "to_id", nullable = false)
@org.hibernate.annotations.LazyToOne(org.hibernate.annotations.LazyToOneOption.NO_PROXY)
@org.hibernate.annotations.OptimisticLock(excluded = false)
@org.hibernate.annotations.Fetch(org.hibernate.annotations.FetchMode.SELECT)
@org.hibernate.annotations.NotFound(action = org.hibernate.annotations.NotFoundAction.EXCEPTION)
private Foo to;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Foo getFrom() {
return from;
}
public void setFrom(Foo from) {
this.from = from;
}
public Foo getTo() {
return to;
}
public void setTo(Foo to) {
this.to = to;
}
}