Я строю объектную сеть (структуру) для представления JSF 2 с сущностями из базы данных.После построения view-object-tree (в конце цикла) все выглядит хорошо.Непосредственно после цикла «for» я повторяю отладку всего «view-object-tree», но затем в списке появляются дубликаты с неправильными отображениями (поскольку PON может находиться в разных группах с одинаковым именем, но с разными POM (ценами)).Проблема в спящем режиме, но я не понимаю, почему это происходит.Проблема решается путем удаления недопустимых данных / объектов или отсоединения объекта от спящего режима.Но почему и где это происходит?
Вот сеть объектов базы данных:
Product -> POG -> (list)POM -> [PON, POV]
-> (list)POM -> [PON, POV]
-> (list)POM -> [PON, POV]
POG - это объект группы (продукт может иметь несколько групп) POM - это объект отображения междуgroup (POG) и имена (pon) и значения (pov)
Для представления, которое я добавил в объект POG, кратковременный список pon для дерева представления, с помощью которого легко построить это дерево:
Дерево в представлении (вывод html)
GroupName
- Let's suppose we have the following values and names POG(Bestseller configuration)
- Size: [3,5,6]
- Length: (30,50,90)
Размер и длина - объекты PON 3,5,6
и 30,50,90
- значения POV, POM - это ссылка для администратораактивированные значения для продукта.(Пример: PON.id -> POV.id
и с каким POM сопоставляется, с какой суммой.
POG (ProductOptionGroup)
@Entity
public class ProductOptionGroup implements Serializable, Comparable<ProductOptionGroup> {
private static final long serialVersionUID = 1337443319888729961L;
public ProductOptionGroup() {
}
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@SequenceGenerator(name = "pog_gen", sequenceName = "pog_id_seq")
private Long id;
@Column(columnDefinition="VARCHAR(128)")
private String name;
@ManyToOne @JoinColumn
private Artikel artikel;
private int pos;
private BigDecimal vk_netto; // Dieser Betrag, erhöht (sofern > 0) oder reduziert (sofern <0) den ArtikelGrundpreis
@OrderBy(value = "position asc")
@OneToMany(mappedBy="pog",orphanRemoval=true) @Cascade(value={CascadeType.ALL})
private List<ProductOptionMapping> lst_pom = new ArrayList<>();
// Für View im Adminbereich, Userbereich leider benötigt.
@Transient
private List<ProductOptionName> lst_pon = new ArrayList<>();
ProductOptionMapping (POM)
@Entity
public class ProductOptionMapping implements Serializable,Comparable<ProductOptionMapping> {
private static final long serialVersionUID = -122661663595010649L;
public ProductOptionMapping() {
// TODO Auto-generated constructor stub
}
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@SequenceGenerator(name = "pom_gen", sequenceName = "pom_id_seq")
private Long id;
@OneToOne @JoinColumn
private ProductOptionName productOptionName;
@OneToOne @JoinColumn
private ProductOptionValue productOptionValue;
@OneToOne @JoinColumn
private Artikel artikel;
@OneToOne @JoinColumn
private ProductOptionGroup pog;
private int position = 0; // sofern es optionen gibt, muss eine default Selection vorhanden sein
private int active = 1;
private BigDecimal preis_netto = new BigDecimal("0.00");
private BigDecimal preis_mwst = new BigDecimal("0.00");
private BigDecimal preis_brutto = new BigDecimal("0.00");
private BigDecimal prozentaufschlag = null;
private String addAmountChar = "+";
private String artikelnr;
ProductOptionName
@Entity
public class ProductOptionName implements Serializable, Comparable<ProductOptionName> {
private static final long serialVersionUID = 348695269475690117L;
public ProductOptionName() {
// TODO Auto-generated constructor stub
}
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@SequenceGenerator(name = "pon_gen", sequenceName = "pon_id_seq")
private Long id;
@Column(columnDefinition="TEXT")
private String pon_name;
private int position;
private String internal_identifier; // Wenn es mehrere mit dem selben namen gibt, zur Unterscheidung; zwei Hersteller haben gleiche PON.name aber andere POV Werte
@Transient
private List<ProductOptionMapping> lst_pom = new ArrayList<>();
ProductOptionValue
@Entity
public class ProductOptionValue implements Serializable, Comparable<ProductOptionValue> {
private static final long serialVersionUID = 4765465078744219823L;
public ProductOptionValue() {
// TODO Auto-generated constructor stub
}
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@SequenceGenerator(name = "pov_gen", sequenceName = "pov_id_seq")
private Long id;
private String pov_value;
@OneToOne @JoinColumn
private ProductOptionName productOptionName;
private int position;
private String artikelnummer;
@Fetch (FetchMode.SELECT)
@OneToOne @JoinColumn @Cascade(value={CascadeType.ALL})
private Images image;
Со следующим кодом япостроение дерева для представления JSF. Там, где у каждого POG есть временный список pon. Внутри каждого PON вложенный список POM вложен (см. код), а также имеется один объект POV для хранения значения.
for(ProductOptionGroup POG : artikel.getLst_pog()) {
POG.setLst_pon(new ArrayList<ProductOptionName>());
for(ProductOptionMapping POM : POG.getLst_pom()) {
if(POM.getActive() == 0)
continue;
ProductOptionName pon = null;
// Bereits in Liste?
for(ProductOptionName iPON : POG.getLst_pon()) {
if(iPON.getId().equals(POM.getProductOptionName().getId())) {
pon = iPON;
break;
}
}
// Nein, neu anlegen
if(pon == null) {
pon = POM.getProductOptionName();
POG.getLst_pon().add(pon);
session.evict(pon);
}
session.evict(POM);
pon.getLst_pom().add(POM);
}
for(ProductOptionName PON : POG.getLst_pon())
for(ProductOptionMapping POM : PON.getLst_pom())
System.out.println("InitProduktAttribute BEFORE SORT :: POG.id " + POG.getId() + " POG.name" + POG.getName() + " POM " + POM.getId() + " POM.pog.id " + POM.getPog().getId() + " POV.name " + POM.getProductOptionName().getPon_name() + " POV.name " + POM.getProductOptionValue().getPov_value());
session.evict(POG);
}
for(ProductOptionGroup POG : artikel.getLst_pog())
for(ProductOptionName PON : POG.getLst_pon()) {
//Collections.sort(PON.getLst_pom());
for(ProductOptionMapping POM : PON.getLst_pom())
System.out.println("InitProduktAttribute AFTER SORT :: POG.id " + POG.getId() + " POG.name" + POG.getName() + " POM " + POM.getId() + " POM.pog.id " + POM.getPog().getId() + " POV.name " + POM.getProductOptionName().getPon_name() + " POV.name " + POM.getProductOptionValue().getPov_value());
}
Внутри цикла for в строке отладки: InitProduktAttribute ПЕРЕД СОРТИРОВКОЙ список верен.
После цикла в строке отладки: InitProduktAttribute ПОСЛЕ СОРТИРОВКИ список содержит дублирующиеся объектыPOM в неправильном списке POG.lst_pon
Пример: InitProduktAttribute ПЕРЕД СОРТИРОВКОЙ :: POG.id 26575 POG.nameBestseller POM 380966 POM.pog.id 25116 POV.name Fussrollen POV.name für harte Böden (Паркетт, ЛаминатПВХ)EFORE SORT :: POG.id 26575 POG.nameBestseller POM 380967 POM.pog.id 26575 POV.name Fussrollen POV.name für weiche Böden (Teppich)
InitProduktAttribute ПОСЛЕ СОРТА :: POG.id 25116 POG.nameGroupN0 # 1 POM 380966 POM.pog.id 25116 POV.name Fussrollen POV.name für harte Böden (Parkett, Laminat, PVC) InitProduktAttribute ПОСЛЕ СОРТА :: POG.id 25116 POG.nameGroup N0 # 1 POM 380967 POM.pog.id26575 POV.name Fussrollen POV.name für weiche Böden (Teppich) InitProduktAttribute ПОСЛЕ СОРТА :: POG.id 26575 POG.nameBestseller POM 380966 POM.pog.id 25116 POV.name Fussrollen POV.name für harte Боден Лакен, Паркет,) InitProduktAttribute ПОСЛЕ СОРТА :: POG.id 26575 POG.nameBestseller POM 380967 POM.pog.id 26575 POV.name Fussrollen POV.name für weiche Böden (Teppich)
Я удалил Collections.sort, но это не изменитсячто-нибудь.Как я уже писал ранее, мне нужно выполнить session.evict объектов при вставке в дерево (для просмотра), чтобы получить правильную сеть объектов.Без session.evict (отсоединение объектов) я получил двойные и неправильные результаты.