2011-12-20 12 views
8

Mam klasę danych dla hibernacji związaną z tabelą; wyobrazić podmiotu Person takiego:Hibernacja: obiekt danych z dynamiczną nazwą tabeli przy pomocy Adnotacji

@Entity 
@org.hibernate.annotations.Proxy(lazy=false) 
@Table(name="Person", schema="MySchema") 
@Inheritance(strategy=InheritanceType.SINGLE_TABLE) 
public class ProfileData implements Serializable { 

    private static final long serialVersionUID = -844564646821609090L; 

    public PersonData() { 
    } 

    @Column(name="idPerson", nullable=false, unique=true) 
    @Id 
    ... 

muszę tworzyć tabele zabytkowych przez lata tej tabeli: Person2010, Person2011, Person2012 ... Czy jest to możliwe bez tworzenia nowych obiektów danych? Może według parametru ...? Nie wiem.

Klasa Entity jest taka sama, zmienia nazwę tabeli i konstruktora.

Odpowiedz

18

Kolejny Architektura, bardziej complez ale elegancki:

TAK, można zmienić nazwy tabeli przy użyciu NamingStrategies:

public class MyNamingStrategy extends DefaultNamingStrategy { 
    ... 
    @Override 
    public String tableName(String tableName) { 
     return tableName+yearSuffixTable; 
    } 
    ... 
} 

A jeśli chcesz używać tabel _year, musisz utworzyć sesję z Hibernate, która zastąpi nazwy tabel rhe:

SessionFactory sessionFactory; 
    Configuration config = new AnnotationConfiguration() 
         .configure("hibernate.cfg.xml") 
         .setNamingStrategy(new MyNamingStrategy()); 
    sessionFactory = config.buildSessionFactory(); 
    session = sessionFactory.openSession(); 

Dla mojej architektury tworzę sesję po roku i zapisuję ją w Mapie aplikacji, aby uzyskać dostęp, kiedy jej potrzebuję.

Dzięki.

3

Powinieneś wypróbować Hibernate Envers dla danych historycznych.

+0

dziękuje. Zamierzam przestudiować to dla mojej aplikacji. Jeśli to rozwiąże mój problem, ustawię twoją odpowiedź jako poprawną :) – ganzux

+0

Envers jest łatwa i być może rozwiązaniem, ale ... Jak mogę ustawić przyrostek tabeli Kontrolowanej dynamicznie? Muszę oddzielać dane przez lata, ponieważ mam milion danych na tabelę i muszę je wyszukać. Dzięki – ganzux

+0

Dlaczego nie możesz po prostu wyszukać na jednym stole? Dobry DBMS powinien być w stanie sobie z tym poradzić. – tobiasbayer

1

W trybie hibernacji mapujesz 1 klasę na 1 tabelę. Nie można ponownie użyć tej samej jednostki, aby dynamicznie mapować kilka tabel.

jest całkiem dobrym rozwiązaniem dla danych historycznych, ale nadal nie będzie można zrobić tego, co próbujesz (dynamicznie zwiększać liczbę tabel bez dotykania jednostek enkoderów).

+0

Dzięki. Zamierzam przestudiować to dla mojej aplikacji. Jeśli to rozwiąże mój problem, ustawię twoją odpowiedź jako poprawną :) – ganzux

+0

Envers jest łatwa i być może rozwiązaniem, ale ... Jak mogę dynamicznie ustawić przyrostek tabeli Kontrolowanej? Muszę oddzielać dane przez lata, ponieważ mam milion danych na tabelę i muszę je wyszukać. Dzięki – ganzux

+0

Nie możesz. ORMy nie oferują takiego poziomu elastyczności, jeśli naprawdę chcesz pójść z tym ** złym ** projektem, który zaproponujesz, wtedy będziesz musiał zrezygnować z Hibernate i Envers i użyć bezpośredniego SQL. – edutesoy

1

Dzięki @CodeBrickie i @edutesoy znalazłem Envers.

Skonfiguruję plik konfiguracji hibernacji z sufiksem AUD i tworzę nowe pliki konfiguracji hibernacji rocznie (hibernate.cfg.2009.xml, hibernate.cfg.2010.xml, hibernate.cfg.2011.xml ...) z sufiksem roku.

Kiedy zapisuję dane, zawsze jest to audyt w tabeli AUD. 1 stycznia automatycznie:

  • TABELA AUD zmieniana jest na tabelę _PAST_YEAR.
  • Utworzono nową tabelę _AUD.
  • Nowy plik hibernate.cfg.past_year.xml jest tworzony z nowym sufiksem.

Kiedy potrzebuję uzyskać dane, ładuję odpowiedni plik konfiguracji hibernacji.

Nadzieja to pomaga innym :)

1
@Table(name="emd_employee_1001") 

W powyższej nazwy pliku adnotacji może przekazać jako parametr, na przykład

x=1001 
@Table(name="emd_employee_+x+") 
+2

Tak, ok, ale po zainicjowaniu obiektu danych nie mogę zmienić nazwy. – ganzux

0

modyfikowane w czasie wykonywania (myślę, że to najlepszy sposób):

Session session = super.getSession(); 
    SQLQuery query = session.createSQLQuery("raw sql"); 
    query.setParameter(":abc", "value"); 
    query.addEntity(Some.class); 
    return query.list(); 
Powiązane problemy