BG Development


  Reply to this topicStart new topicStart Poll

> Hibernate и soft delete
uccie
Публикувано на: 25-08-2017, 21:24
Quote Post



Име:
Група: Потребител
Ранг: Редовен член

Мнения: 552
Регистриран на: 16.10.12



Имам малък проблем с Hibernate. Надявам се, че някой се е сблъсквал с нещо подобно и може да удари едно рамо.

Нека приемем, че имаме следните три таблици:

CODE
TABLE_A (A_ID, A_DELETED_FLAG)
TABLE B (B_ID, B_DELETED_FLAG)
TABLE_AB (AB_A_ID, AB_B_ID)


TABLE_AB реализира m:n-връзка между TABLE_A и TABLE_B.

TABLE_A и TABLE_B имат своя Hibernate еквивалент:

CODE
public class A {
      private String id;
      private boolean deleted;
      private Set<B> bs;
       ...

}

public class B {
      private String id;
      private boolean deleted;
      private Set<A> as;
       ...
}

А.hbm.xml

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping default-lazy="false" default-access="field">
      <class
            name="com.xyz.entities.A" table="TABLE_A">
            <id name="id" type="string" access="property">
                  <column name="A_ID" length="36" />
                  <generator class="assigned" />
            </id>
            <property name="deleted" type="yes_no">
                  <column name="A_DELETED_FLAG" length="1">
                        <comment>Attribute: deletedFlag</comment>
                  </column>
            </property>
            <set name="bs" table="AB"  inverse="false" lazy="false" fetch="select" cascade="save-update">
                  <key>
                        <column name="AB_A_ID" not-null="true" />
                  </key>
                  <many-to-many
                        entity-name="com.xyz.entities.B">
                        <column name="AB_B_ID" not-null="true" />
                  </many-to-many>
            </set>
      </class>
</hibernate-mapping>

B.hbm.xml

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping default-lazy="false" default-access="field">
      <class
            name="com.xyz.entities.B" table="TABLE_B">
            <id name="id" type="string" access="property">
                  <column name="B_ID" length="36" />
                  <generator class="assigned" />
            </id>
            <property name="deleted" type="yes_no">
                  <column name="B_DELETED_FLAG" length="1">
                        <comment>Attribute: deletedFlag</comment>
                  </column>
            </property>
            <set name="as" table="AB" inverse="true" lazy="true" fetch="select">
                  <key>
                        <column name="AB_B_ID" not-null="true" />
                  </key>
                  <many-to-many
                        entity-name="com.xyz.entities.A">
                        <column name="AB_A_ID" not-null="true" />
                  </many-to-many>
            </set>
      </class>
</hibernate-mapping>


ADAO и BDAO абстрахират комуникацията с базата данни.


Заданието е следното:

Да се реализира метод List<A> getAs() в ADAO, който връща всички А, при които deleted e false. Освен това множеството bs трябва да бъде изчистено от
B-та, при които deleted е true. Представете си, че A са промоции и B са магазини. Методът трябва да връща всички активни промоции със съответното множество на
все още действащи магазини. Моят метод връща всички промоции, които имат магазини и "игнорира" промоциите без магазини, което е очевидна грешка.

CODE
public List<A> getAs() {
      Criteria criteria = getCriteriaForA();
      criteria.add(Restrictions.eq("deleted", Boolean.FALSE));
      criteria.createAlias("bs", "b", JoinType.LEFT_OUTER_JOIN);
      criteria.add(Restrictions.eq("b.deleted", Boolean.FALSE));
      List<A> as = (List<A>) criteria.list();
      return as;
}


Идеи?

P.S. Софтуерът е доста старичък и не използва JPA или анотации (old school XML).


PMEmail Poster
Top
FidelDahan
Публикувано на: 25-08-2017, 23:01
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 2345
Регистриран на: 12.06.08



Нямам много идея от детайлите в Hibernate, но една съвсем друга идея - два допълнителни view-a които извеждат само активните промоции и само действащите магазини.

CREATE VIEW view_a AS SELECT ... FROM table_a WHERE deleted = false;
-- същото за table_b

Join-таблицата TABLE_AB си остава същата, но DAO-тата извличат данни от view-тата, а не от същинските таблици. По този начин филтрирането се получава автоматично на по-ниско ниво и DAO-тата може би ще бъдат по-прости. Но пък се налага разширение на схемата на базата.
PMEmail Poster
Top
uccie
Публикувано на: 26-08-2017, 07:32
Quote Post



Име:
Група: Потребител
Ранг: Редовен член

Мнения: 552
Регистриран на: 16.10.12



QUOTE (FidelDahan @ 25-08-2017, 23:01)
Нямам много идея от детайлите в Hibernate, но една съвсем друга идея - два допълнителни view-a които извеждат само активните промоции и само действащите магазини.

CREATE VIEW view_a AS SELECT ... FROM table_a WHERE deleted = false;
-- същото за table_b

Join-таблицата TABLE_AB си остава същата, но DAO-тата извличат данни от view-тата, а не от същинските таблици. По този начин филтрирането се получава автоматично на по-ниско ниво и DAO-тата може би ще бъдат по-прости. Но пък се налага разширение на схемата на базата.

Това е интересна идея, Fidel! Ако няма по-лесно решение ще я пробвам (но искрено се надявам, че има 🤔).
PMEmail Poster
Top
thrawn
Публикувано на: 26-08-2017, 13:41
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 1846
Регистриран на: 17.01.17



Ако не можеш да намериш решение с hibernate си направи парсер за конфигурационния му файл и си ползвай директно jdbc. Идеята на парсера е да не ти се налага да посочваш едни и същи конфигурационни данни на разпични места.
Не виждам смисъл за нещо толкова просто да се ползва описаната логика. Подобни подходи са удачни когато sql и базата данни не предлагат адекватно решение.

---edit---
http://www.mkyong.com/hibernate/hibernate-...query-examples/ това изглежда удачно решение за мапване на обикновена заявка.

Това мнение е било редактирано от thrawn на 26-08-2017, 16:27
PMEmail Poster
Top
uccie
Публикувано на: 27-08-2017, 15:25
Quote Post



Име:
Група: Потребител
Ранг: Редовен член

Мнения: 552
Регистриран на: 16.10.12



QUOTE (thrawn @ 26-08-2017, 13:41)
Ако не можеш да намериш решение с hibernate си направи парсер за конфигурационния му файл и си ползвай директно jdbc. Идеята на парсера е да не ти се налага да посочваш едни и същи конфигурационни данни на разпични места.
Не виждам смисъл за нещо толкова просто да се ползва описаната логика. Подобни подходи са удачни когато sql и базата данни не предлагат адекватно решение.

---edit---
http://www.mkyong.com/hibernate/hibernate-...query-examples/ това изглежда удачно решение за мапване на обикновена заявка.

Мерси, thrawn! Не искам да чупя абстракциите като намесвам JDBC. За сега написах един трансформатор (ResultTransformer), ако прави проблеми ще го заменя с идеята на Фидел.
PMEmail Poster
Top
0 потребители преглеждат тази тема в момента (0 гости, 0 анонимни потребители)
Потребители, преглеждащи темата в момента:

Topic Options Reply to this topicStart new topicStart Poll

 


Copyright © 2003-2018 | BG Development | All Rights Reserved
RSS 2.0