2009-03-13 10 views
2

Ich habe ein Foo, das eine Beziehung zu vielen Bars hat.Kann ich eine Hibernate-Beziehung mit einem Filter angeben?

Wenn ich bars in meinem System lösche, möchte ich sie aus irgendeinem verrückten Geschäftsgrund in der Datenbank behalten, also setze ich ein gelöschtes Feld auf true.

Kann ich in meinem Hibernate-Mapping angeben, dass meine Sammlung nur Elemente enthalten soll, in denen dieses Feld falsch ist?

Antwort

2

Hibernate bietet filters um dies zu erreichen.

Beispiel Bohnen:

public class Foo { 
    private Long id; 
    private String text; 
    private Set<Bar> bars = new HashSet<Bar>();  
    // constructors, getters, setters 
} 

public class Bar { 
    private Long id; 
    private boolean deleted; 
    private String text; 
    // constructors, getters, setters 
} 

Beispiel Mappings NB: filter Element

<hibernate-mapping package="org.nkl.hib"> 
    <class name="Foo"> 
    <id name="id" column="FOO_ID"> 
     <generator class="sequence" /> 
    </id> 
    <property name="text" /> 
    <set name="bars" cascade="all" fetch="join"> 
     <key column="FOO_ID" /> 
     <one-to-many class="Bar" /> 
     <filter name="deleted" condition=":deleted = deleted" /> 
    </set> 
    </class> 
    <filter-def name="deleted"> 
    <filter-param name="deleted" type="boolean" /> 
    </filter-def> 
</hibernate-mapping> 

<hibernate-mapping package="org.nkl.hib"> 
    <class name="Bar"> 
    <id name="id" column="BAR_ID"> 
     <generator class="sequence" /> 
    </id> 
    <property name="text" /> 
    <property name="deleted" /> 
    </class> 
</hibernate-mapping> 

Beispiel Unit-Test:

public class FooBarTest { 

    private static SessionFactory sessionFactory; 

    @AfterClass 
    public static void closeSessionFactory() { 
     sessionFactory.close(); 
    } 

    @BeforeClass 
    public static void setupSessionFactory() { 
     Configuration configuration = new Configuration(); 
     configuration.configure(); 
     sessionFactory = configuration.buildSessionFactory(); 
    } 

    @Test 
    public void testBarFilter() { 
     doInTransaction(new Command() { 
      public void execute(Session session) { 
       Foo foo = new Foo("foo"); 
       foo.addBar(new Bar("bar1")); 
       foo.addBar(new Bar("bar2")); 
       foo.addBar(new Bar("bar3")); 
       session.save(foo); 
      } 
     }); 

     doInTransaction(new Command() { 
      public void execute(Session session) { 
       Bar bar = (Bar) session.createQuery(
         "from Bar b where b.text = 'bar2'"). 
         uniqueResult(); 
       bar.setDeleted(true); 
       session.update(bar); 
      } 
     }); 

     doInTransaction(new Command() { 
      public void execute(Session session) { 
       session.enableFilter("deleted"). 
         setParameter("deleted", Boolean.FALSE); 
       Foo foo = (Foo) session.createQuery("from Foo"). 
         uniqueResult(); 
       assertEquals(2, foo.getBars().size()); 
      } 
     }); 
    } 

    private void doInTransaction(Command command) { 
     Session session = sessionFactory.openSession(); 
     Transaction tx = session.beginTransaction(); 
     command.execute(session); 
     tx.commit(); 
     session.close(); 
    } 
} 

interface Command { 
    public void execute(Session session); 
} 
3

Sie können auch eine SQL-Anweisung zu halten verwenden stuff out, mit der wo Attribut: Beispiel Bit Ihre Hibernate Mapping-Datei für eine bestimmte Beziehung:

<set name="specialConditions" cascade="none" order-by="sortOrder, Text1" 
    where="Discriminator in ('SPECIAL-CURF-AGREEMENT') and active = 'Y'" 
    sort="unsorted" inverse="false" mutable="true" optimistic-lock="true" 
    embed-xml="true">  
    <key column="parentID" not-null="false" on-delete="noaction" /> 
    <one-to-many class="au.gov.abs.maserati.domain.entity.Condition" not-found="exception" embed-xml="true" /> 
</set> 
+0

Cool, ich das nicht wusste und schon seit Jahren Hibernate wurde jetzt mit. – javashlook

Verwandte Themen