Sunteți pe pagina 1din 16

Universitatea Alexandru Ioan Cuza din Iasi

Facultatea de Economie si Administrarea Afacerilor


An 3, Informatic Economic
Proiectarea Sistemelor Informationale
3. Modelul fizic
Pn aici ne-am ocupat de:
modelul conceptual, redat prin diagrama de clase ce includea entitile
persistente. Ea a fost realizat folosind standardul UML i instrumentul Visual
Paradigm.
modelul logic al datelor, pentru care a fost adoptat modelul relaional i care a fost
redat sub forma unei diagrame entitate-relaie. Acest model a fost obinut prin
transformarea modelului conceptual.
Acum ne vom ocupa de modelul fizic. El presupune implementarea modelelor
conceptual i logic folosind un limbaj de programare i/sau un SGBD.
Obinerea modelului fizic de persisten presupune dou transformri:
1) din diagrama de clase UML n clase folosind sintaxa limbajului de programare ales;
2) din diagrama entitate-relaie n tabelele bazei de date folosind SGBD-ul ales pentru
implementarea bazei de date.

n ciclul de via al aplicaiilor moderne, aceste dou tranformri au loc ntr-o manier
secvenial, conform schemei din figura 8. Prima faz presupune transformarea diagramei de
clase UML n limbajul de implementare a aplicatiei, iar n faza a doua se obine schema bazei
de date prin transformarea codului de implementare a claselor, rezultat n prima faz.


Figura 8 Ciclul de transformare a structurilor de persisten

Ambele faze de transformare pot fi automatizate sau efectuate manual. Astfel:
1) fiecare instrument de modelare UML ofer motoare de generare cod pe baza
diagramelor (forward engineering) sau de obinere de diagrame pe baza codului
existent (reverse engineering).
2) Limbajele moderne ofer cadre de lucru (frameworks) ORM (Object-Relational
Mappings) care vor genera/sincroniza clasele de obiecte cu schema bazei de
date pe baza informaiilor suplimentare asociate claselor (prin cele dou tehnici
uzuale: adnotri sau fiiere XML).
Universitatea Alexandru Ioan Cuza din Iasi
Facultatea de Economie si Administrarea Afacerilor
An 3, Informatic Economic
Proiectarea Sistemelor Informationale
Pentru implementarea modelului fizic am ales limbajul Java i framework-ul de persisten
JPA (Java Persistence API)
1
, versiunea de implementare Hibernate
2
(open-source si utilizat
pe scar larg in industrie). Trebuie reinut c, maniera general de abordare prezentat n
continuare este perfect valid pentru orice alt limbaj de programare orientat pe obiecte. Astfel,
far ndoial, o implementare .NET (VB sau C#) va fi 99% similar deoarece exist o
implementare Hibernate si pentru .NET (vezi link-ul http://www.hibernate.org/).

3.1 Implementarea claselor (prima faz a transformrii)

Implementarea complet exemplificat pentru diagrama de clase din figura 2 este
disponibil ntr-un proiect Eclipse (un mediu de dezvoltare foarte cunosctut utilizat si la
disciplina Programare II) cu numele SGSM-Model. Pai de efecutat:
1) Dezarhivati continutul arhivei zip gasite pe Portal FEAA (disciplina PSI). Vei obine dou
directoare cu cele dou proiecte: modelul (SGSM-Model) i o parte de implementare pentru
interfaa grafic (SGSM-GUI).
2) Creai un nou Workspace n directorul radacin al celor dou proiecte.
3) Importai cele dou proiecte n respectivul workspace (File/import/General/ Existing projects
into workspace/ selectai directorul rdcin/ bifai cele dou proiecte).
4) Motorul Hibernate este deja inclus n respectivul proiect (vezi directorul SGSM-Model/lib) iar
bibliotecile de clase sunt ncrcate la nivelul proiectului (Project/Properties/Jaba build Path).
Aceast operaiune, de import al bibliotecilor third parties utilizate de un anumit proiect
este, evident, obligatorie.

La deschiderea proiectului SGSM-Model veti vedea o structur precum cea din figura 9.


1
Recomandam cu insisten o scurt revizuire a cunotinelor dobandite la discilina Programare II
2
http://www.hibernate.org/
Universitatea Alexandru Ioan Cuza din Iasi
Facultatea de Economie si Administrarea Afacerilor
An 3, Informatic Economic
Proiectarea Sistemelor Informationale

Figura 9 Structura proiectului SGSM-Model



Universitatea Alexandru Ioan Cuza din Iasi
Facultatea de Economie si Administrarea Afacerilor
An 3, Informatic Economic
Proiectarea Sistemelor Informationale

n faza n care suntem acum, ne intereseaz doar clasele-entitate (pachetul
ro.uaic.feaa.psi.sgsm.model.entities), care reflect ntocmai structurile din diagrama
de clase din figura 2.
PENTRU MOMENT, vom ignora adnotrile specifice ORM-JPA. La acestea vom reveni
n seciunea urmtoare.

Pentru c structurile sunt foarte simple (se apeleaz la cunotine fundamentale de
programare), nu vom descrie fiecare clas, ci doar cteva reguli importante privind deciziile
luate n implementarea anumitor aspecte i codul aferent claselor respective. Astfel:
1) Toate clasele respect ablonul de lucru Java Beans, care reflect principiul
ncapsulrii:
a. Atributele sunt declarate cu vizibilitate private.
b. Pentru fiecare atribut exista cte o metod set/get public (metode de acces si
modificare cu scop de a oferi acces la valoarea atributului privat).

Sablonul utilizat blocheaza accesul direct la atribut. Cu alte cuvinte, un client NU va putea
executa o secven de cod precum cea de mai jos (va obine erori de compilare din pricina
specificatorului de vizibilitate private):

Document x = new Document ();
x.dataOperare = new Date();
sau
Date data = x.dataOperare;

Pentru a accesa valoarea atributului dataOperare, clientul va fi obligat s utilizeze
metodele publice corespunzatoare:

x.setDataOperare(new Date());
Date data = x.getDataOperare();

Acest ablon este aplicabil n toate limbajele. Este recomandat a fi utilizat i, n fapt, este
omniprezent n toate aplicaiile profesionale. Avantaje obinute sunt:

a) Este foarte uor de implementat un atribut de tip read-only. Astfel, s presupunem c,
n exemplul de mai sus, dataOperare nu ar trebui s fie accesibil la modificare.
Valoarea acestui atribut ar trebui s fie automat asociat la crearea unui obiect nou
Document (fie prin constructor fie prin asocierea direct la nivelul declaraiei
atributului), dup care va fi posibil doar citirea valorii, nu i modificarea ei.
Implementarea este foarte simpl: dac nu declarm o metod public de modificare
(setDataOperare), va fi practic imposibil modificarea valorii respective.
b) Este foarte uor de adaugat cod suplimentar la momentul accesului sau modificrii
valorii, fr vreo implicaie pentru client (nu va trebui s se modifice nimic la nivelul
clientului). Astfel:
Universitatea Alexandru Ioan Cuza din Iasi
Facultatea de Economie si Administrarea Afacerilor
An 3, Informatic Economic
Proiectarea Sistemelor Informationale
I. Presupunem c dorim implementarea unei restricii prin care data operare
trebuie s fie mai mare sau egal cu data documentului. Vom modifica
metodele setDataOperare si setDataDocument astfel nct s verifice
aceast restricie i s genereze o eroare n caz de nclcare a regulii
(foarte simular conceptului de trigger la nivelul bazei de date).
II. Presupunem c dataOperare trebuie s fie prezentat public sub form de
dat calendaristic dar intern trebuie stocat prin intermediul a trei atribute
zi, luna, an. Pentru a implementa o asemenea cerin:
i. Se declar 3 atribute private de tip Integer: zi, luna, an
ii. Metoda public getDataOperare se modifc pentru a construi i returna
un obiect Date pe baza celor trei atribute interne
iii. Metoda public setDataOperare se modifc pentru a extrage din
parametrul de tip Date primit cele trei pari componente: zi, luna, an.

2) Implementarea claselor i a relaiilor M:1 unidirecionale. Singurul aspect de
remarcat n astfel de situaii este includerea atributului gestiune de tip Gestiune
pentru implementarea navigabilitii dinspre clasa Consum spre clasa Gestiune.

@Entity
public class Consum extends Document{

String numarComanda;
String locConsum;
@ManyToOne
Gestiune gestiune;

public String getNumarComanda() {
return numarComanda;
}
public void setNumarComanda(String numarComanda) {
this.numarComanda = numarComanda;
}
public String getLocConsum() {
return locConsum;
}
public void setLocConsum(String locConsum) {
this.locConsum = locConsum;
}
public Gestiune getGestiune() {
return gestiune;
}
public void setGestiune(Gestiune gestiune) {
this.gestiune = gestiune;
}

}

Universitatea Alexandru Ioan Cuza din Iasi
Facultatea de Economie si Administrarea Afacerilor
An 3, Informatic Economic
Proiectarea Sistemelor Informationale
3) Implementarea relaiilor 1:M bidirecionale. Atributele cu multiplicitatea mai mare
de 1 se reprezint sub forma coleciilor. n cazul relaiilor 1:M bidirecionale,
implementarea navigrii relaiei dinspre partea 1 (DocInsotitor) spre partea Multe
(Receptie) impune includerea n clasa DocInsotitor a unui atribut de tip Receptie, care
va avea multiplicitatea mai mare ca 1 i care va fi implementat ca o colecie. Coleciile
respect un anumit ablon de implementare, astfel (lum exemplul relaiei ntre
DocInsotitor si Receptie):
a. Colecia se reprezint intern folosind tipul cel mai convenabil prin intermediul
unui atribut private. In cazul de fa este folosit o implementare de tip Set, din
dou raiuni:
i. Intr-o colecie de tip Set obiectele sunt pstrate garantat ntr-o ordine bine
definit (vezi cursul Programare II).
ii. Implementarea JPA Hibernate recomand acest tip de colecie pentru
relaiile One-To-Many (da, acest aspect este important n seciunea
urmtoare, dar venim s-l descriem aici).
b. Colecia este apoi expus public prin intermediul a cel puin trei metode:
i. Dou metode pentru adugare/tergere elemente n/din colecie.
ii. Gestionarea relaiei inverse (dinspre copil spre printe).
iii. O metod de citire a coleciei ce returneaz o clon a obiectului.
ATENIE clientul nu trebuie niciodat s poat modifica n mod direct
numrul de elemente al coleciei (vezi restriciile de implementare de mai
sus privind managementul relaiilor inverse). Ca urmare, vom expune
colecia sub forma unui tip uzual (List) dar de tip read-only.

Urmrii cu atenie n exemplul reinut mai jos urmtoarele aspecte:
a) Cele 2 metode de actualizare a atributului receptii de tip colecie: addReceptie i
removeReceptie.
b) n cadrul celor 2 metode se gestioneaz i relaia invers prin invocarea metodei
setDocInsotitor din clasa Receptie.
c) Metoda getReceptii care furnizeaz lista recepiilor pentru un document nsoitor
sub forma unei liste read-only.

@Entity
public class DocInsotitor extends Document {
private String mijlTransport;

@ManyToOne
private DocInsotitor docInsotitorStornat;

@ManyToOne
private DocInsotitor docInsotitorDeStornare;

@ManyToOne
private Furnizor furnizor;

@OneToMany(mappedBy = "docInsotitor", cascade = CascadeType.ALL, fetch
= FetchType.EAGER)
private Set<Receptie> receptii = new HashSet<Receptie>();

Universitatea Alexandru Ioan Cuza din Iasi
Facultatea de Economie si Administrarea Afacerilor
An 3, Informatic Economic
Proiectarea Sistemelor Informationale
// ---------------metode pentru managementul colectiei receptii-----//

public void addReceptie(Receptie receptie) {
this.receptii.add(receptie);
receptie.setDocInsotitor(this);
}

public void addReceptie(Gestiune gestiune) {
Receptie r = new Receptie();
r.setGestiune(gestiune);
this.addReceptie(r);
}

public void removeReceptie(Receptie receptie) {

this.receptii.remove(receptie);
receptie.setDocInsotitor(null);
}

public List<Receptie> getReceptii() {
return Collections.unmodifiableList(new
LinkedList(this.receptii));
}

}


@Entity
public class Receptie extends Document{
@ManyToOne
DocInsotitor docInsotitor;
@ManyToOne
Gestiune gestiune;

Boolean facturaPrimita;

public DocInsotitor getDocInsotitor() {
return docInsotitor;
}
public void setDocInsotitor(DocInsotitor docInsotitor) {
this.docInsotitor = docInsotitor;
}
}

S mai spunem c relaiile de agregare sunt implementate de regul ca fiind navigabile n
ambele sensuri.

4) Implementarea relaiilor M:M bidirecionale. Implementarea acestor relaii este
asemntoare cu situaia anterioar doar c ambele atribute ce vor implementa
relaia de asociere vor fi de tip colecie. n aplicaia noastr nu exist o astfel de
situaie ns, pentru exemplificare, vom analiza relaia ntre clasele BunMaterial i
Categorie i n care vom considera c un bun material se poate regsi n mai multe
categorii, iar o categorie va include mai multe bunuri materiale.

Universitatea Alexandru Ioan Cuza din Iasi
Facultatea de Economie si Administrarea Afacerilor
An 3, Informatic Economic
Proiectarea Sistemelor Informationale
public class BunMaterial {
...
private Collection<Categorie> categorii=new HashSet<Categorie>();

public void addCategorie(Categorie c) {
if(! categorii.contains(c)) {
categorii.add(c);
c.addBunMaterial(this);
}
}

public void removeCategorie(Categorie c) {
if(categorii.contains(c)) {
categorii.remove(c);
c.removeBunMaterial(this);
}
}
}

public class Categorie {

private String denumire;
private Collection<BunMaterial> bunuri = new HashSet<BunMaterial>();

public void addBunMaterial(BunMaterial bun){
if (!this.bunuri.contains(bun)) {
this.bunuri.add(bun);
bun.addCategorie(this);
}
}
public void removeBunMaterial(BunMaterial bun){
if (this.bunuri.contains(bun)) {
this.bunuri.remove(bun);
bun.removeCategorie(this);
}
}
public Collection<BunMaterial> getBunuri() {
return Collections.unmodifiableCollection(bunuri);
}
}


3.2 Maparea claselor i a tabelelor bazei de date - tehnici ORM (a doua faz de
transformare)

Universitatea Alexandru Ioan Cuza din Iasi
Facultatea de Economie si Administrarea Afacerilor
An 3, Informatic Economic
Proiectarea Sistemelor Informationale
n aceast seciune vom realiza cea de-a doua transformare pentru obinerea modelului
fizic, respectiv din codul de implementare a claselor (limbaj) n schema bazei de date. n acest
scop se folosete un cadru de lucru ORM.

In seciunea de fa rmnem la modelul fizic i proiectul Java SGSM-Model descris n
paragraful anterior. Spuneam ca folosim cadrul de lucru JPA (Java Persistence API) si
implementarea Hibernate, o implementare care este disponibil att pentru Java ct i pentru
.NET. Astfel, schema fizic a bazei de date prezentate n figura 3 poate fi creat n mod
automat de catre motorul JPA (n cazul de fa, Hibernate) prin transformarea modelului
obiectual Java n relaii corespunztoare modelului relaional.

Paii de parcurs pentru a genera schema bazei de date sunt urmtorii:
1. Se adauga informaiile suplimentare de persisten la nivelul claselor-entitate. In
exemplul nostru am folosit metoda adnotrilor JPA, metod care presupune adugare
de semantic JPA direct la nivelul clasei Java (n loc de fiiere de proprieti/XML
separate) i descris la disciplina Programare II.
2. Se adauga fisierul META-INF/persistence.xml contine descrierea conexiunii catre baza
de date. In exemplul nostru (vezi proiectul SGSM-Model) folosim baza de date
PostgreSQL cu numele postgres (implict la instalare), instalata local, si o schema
dedicata acestui exemplu cu numele sgsm (user si parola acelasi sgsm).
i) In cazul in care doriti sa folositi o alta baza de de date PostgreSQL (spre exemplu
cea pusa la dispozitie de faculate pentru disciplina BD I), va trebui sa modificati
proprietatile:
<property name="hibernate.connection.url"
value="jdbc:postgresql://localhost:5432/postgres" />

<property name="hibernate.connection.username" value="sgsm" />
<property name="hibernate.connection.password" value="sgsm" />

ii) In cazul in care doriti sa folositi un alt motor de baze de date va trebui sa modificati,
pe langa proprietatile de mai sus, si tipul driverului si dialectul SQL utilizat. Atentie, in
functie de motorul bazei de date, va trebui sa descarcati driverul de pe Internet si sa-
l adaugati ca dependinta la proiect (driverul PostgreSQL este deja asociat
proiectului)
iii) A se observa ca proiectul foloseste valoarea "update"
3
pentru proprietatea esentiala
ce va instrui comportamentul generatorului de schema de baze de date:
<property name="hibernate.hbm2ddl.auto" value="update" />
Aceasta valoare va asigura actualizarea schemei bazei de date la fiecare modificare a
modelului obiectual.

3. TRANSFORMAREA efectiv i generarea schemei bazei de date, n cazul unui proiect
POJO ca al nostru, va avea loc la execuia primei comenzi JPA-QL (este vorba de un
SQL adaptat pentru nevoile modelului obiectual de asemenea prezentat la disciplina

3
Vezi si http://stackoverflow.com/questions/438146/hibernate-question-hbm2ddl-
auto-possible-values-and-what-they-do
Universitatea Alexandru Ioan Cuza din Iasi
Facultatea de Economie si Administrarea Afacerilor
An 3, Informatic Economic
Proiectarea Sistemelor Informationale
Programare II). Astfel, este sufficient s scriei o clas de test n care metoda main ar
avea urmatorul continut:

4. public class FirstTest{
5. public static void main(String[] args){
6.
7. EntityManager em = Persistence.createEntityManagerFactory(
8. "SGSMPersistenceUnit").createEntityManager();
9. em.createQuery("Select loc from Localitate loc").getResultList();
10.
11. }
12. }

Nu vom insista aici asupra elementelor clasice JPA precum @Entity, @ManyToOne,
@OneToMany. Toate acestea le aveti deja explicate in cursul Programare II pe care v
recomandm s-l revizuiti cu atentie (sectiunea JPA, in special). Referitor la acestea, precizm
doar c s-a urmrit simplificarea la maximum a codului, astfel evitnd declararea explicit a
denumirilor de tabele i atribute. Ca urmare, n schema generat vom regsi exact aceleai
denumiri ca i n modelul obiectual. Aceast stare de fapt poate fi, evident, uor de schimbat
prin utilizarea atributelor corespunztoare la nivelul adnotrilor.

n continuare dorim doar sa nuanm anumite decizii de proiectare:
1) In primul rand, observam ca toate clasele entitate extind super-clasa AbstractEntity.
Aceast clas este marcat @MappedSuperclass care instruiete motorul JPA s nu
genereze o tabel distinct ci s includ toate atributele clasei n tabelele generate
pentru fiecare din sub-clasele acesteia. Prin intermediul acestei strategii sunt atinse
urmtoarele aspecte critice privind proiectarea unui model JPA:
a) Toate entitile trebuie s dein un ID (cheia primar) si este recomandat ca
aceast cheie s fie generat pe baza unei secvene n loc de a fi preluat din
modelul domeniului. In spe, o dat asociat, utilizatorul NU trebuie s poat
modifica aceasta valoare a cheii primare. De asemenea, trebuie evitate cu orice
pre cheile compuse, acestea genernd probleme deosebite n managementul
general al aplicaiilor client-server. Ca urmare, id-ul entitilor este delcarat in
superclas i va fi motenit de subclase. Toate celelalte chei candidat din model
vor fi declarate prin atributul unique (exemplu: Localitate.cod) care va determina
generarea unei restricii de unicitate la nivelul atributului.
b) Toate entitile trebuie s prezinte informaii generale privind: data crearii si
modificarii, utilizatorul care a efectuat modificarea etc. Aceste atribute sunt, de
asemenea, localizate la nivelul superclasei, unele dintre ele deinnd valori
implicite.
c) Pentru c n aplicaiile orientate pe date se folosesc in mod intensiv colecii de
obiecte, toate entitile trebuie s implementeze n mod corect operatorii equals()
i hashCode() pe baza ID-ului. Iat de ce aceti operatori vor fi implementai o
singur dat la nivelul superclasei AbstractEntity.
d) Toate entitile trebuie s ofere suport pentru mecanismul OptimisticLocking
(crucial in aplicaiile client-server). Hibernate ofer o implementare standard n
Universitatea Alexandru Ioan Cuza din Iasi
Facultatea de Economie si Administrarea Afacerilor
An 3, Informatic Economic
Proiectarea Sistemelor Informationale
acest sens pe baza atributului marcat @Version (n cazul nostru, atributul cu
acelai nume).
e) In final, scopul fundamental al superclasei AbstractEntity este de a furniza
structura i comportamentul comune tuturor entitilor, oricare ar fi acestea, n
funcie de necesiti.
2) Relatiile de compunere din diagrama de clase, ce reprezint modelul conceptual de
structura, (figura 2) se traduc INTOTDEAUNA prin relaii JPA de tip @OneToMany
bidirecionale (vezi DocumentLiniiDocument, unde exist reciprocitatea
@ManyToOne n clasa-copil. Relaiile de asociere simple, unidirecionale (vezi
ReceptieGestiune) se traduc doar prin relaii de tip ManyToOne la nivelul clasei-
copil. Asemnarea cu mecanismul cheilor straine, in acest caz, este evident, singura
diferen fiind aceea c n modelul relaional referina se face prin valoare in timp ce
in moelul obiectual, prin pointeri. Astfel, urmtoarele dou propoztii sunt echivalente :
a) SQL: select g.denumire from Receptie r inner join Gestiune g on
r.idReceptie=g.id
b) OO: receptie.getGestiune().getDenumire(); unde receptie este o variabil de tip
Receptie.
(inner join este echivalent cu navigabilitatea prin operatorul .)
3) Pentru relaiile de motenire, trebuie stabilit strategia de implementare la nivelul
bazei de date. Exist trei strategii: 1) o singur tabel pentru toate clasele (atributele
claselor-frunz vor avea valori null pentru tipurile vecine) variant care ofer
optimizarea maxim a interogrilor dar mai puin ortodox pentru evanghelitii
modelului relaional; 2) relaii 1:1 ntre super-clas i sub-clase cele mai corecte
din punct de vedere al modelului relaional determin necesitatea unor operaii de
tip Join frecvente i, ca urmare, o vitez de procesare inferioar variantei 1; 3) cte o
tabel pentru fiecare clas-frunz determin multiplicarea cmpurilor comune in
tabele multiple i necesitatea unor operaii asambliste de tip UNION n cazul
interogarilor pe tipurile-printe. In exemplul de fa s-a luat decizia adoptrii stategiei
2. Aceasta abordare va determina generarea urmtoarelor relaii 1:1 n BD:
Document cu DocInsotitor, Receptie i Consum.

In final, vom descoperi ca modelul generat automat este putin diferit fata de cel din figura 3,
avand in vedere elementele de rafinare descrise mai sus, dar elementele generale raman
aceleasi.

In continuare prezentm partea de cod de implementare a claselor care conine adnotrile
JPA i implementarea clasei AbstractEntity.

public abstract class AbstractEntity implements Serializable {

private static final long serialVersionUID = -4803471783122679780L;

public static long getSerialVersionUID() {
return serialVersionUID;
}

Universitatea Alexandru Ioan Cuza din Iasi
Facultatea de Economie si Administrarea Afacerilor
An 3, Informatic Economic
Proiectarea Sistemelor Informationale
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
protected Long id;

/**
* the @Version is used for Optimistic Locking mechanism
*/
@Version
@Column(name = "version")
private Integer version;
private String createdByUser;
private String updatedByUser;

/**
* most used for inheritance strategies
*/
private String entity_type = this.getClass().getSimpleName();

@Temporal(value = TemporalType.TIMESTAMP)
@Column(name = "dateCreated", nullable = false)
private Date dateCreated=Calendar.getInstance().getTime();

@Temporal(value = TemporalType.TIMESTAMP)
@Column(name = "dateUpdated", nullable = false)
private Date dateUpdated=Calendar.getInstance().getTime();

/**
* The default constructor is always needed for JPA.
*/
public AbstractEntity() {
super();
}

public AbstractEntity(Long id) {
this();
this.id = id;

}

/**
* Provide the right equals implementation. Really mandatory. This
* implementation is based on the object's ID. However, if the object
has
* not been yet serialized to the DB, hence, no ID, then provide the
usual
* implementation.
*/
@Override
public boolean equals(Object obj) {
if (id == null)
return super.equals(obj);
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
Universitatea Alexandru Ioan Cuza din Iasi
Facultatea de Economie si Administrarea Afacerilor
An 3, Informatic Economic
Proiectarea Sistemelor Informationale
return false;
final AbstractEntity other = (AbstractEntity) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}

/**
* Provide the right hashcode implementation. Really mandatory. This
* implementation is based on the object's ID. However, if the object
has
* not been yet serialized to the DB, hence, no ID, then provide the
usual
* implementation.
*/
@Override
public int hashCode() {
if (id == null)
return super.hashCode();

final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}

//---------------public GETTERS and SETTERS - the usual Java Beans
approach-----------------------//
public String getCreatedByUser() {
return createdByUser;
}

public Date getDateCreated() {
return dateCreated;
}

public Date getDateUpdated() {
return dateUpdated;
}

public String getEntity_type() {
return entity_type;
}

public Long getId() {
return id;
}

public String getUpdatedByUser() {
return updatedByUser;
}

public Integer getVersion() {
return version;
Universitatea Alexandru Ioan Cuza din Iasi
Facultatea de Economie si Administrarea Afacerilor
An 3, Informatic Economic
Proiectarea Sistemelor Informationale
}

public void setCreatedByUser(String createdByUser) {
this.createdByUser = createdByUser;
}

public void setDateCreated(Date dateCreated) {
this.dateCreated = dateCreated;
}

public void setDateUpdated(Date dateUpdated) {
this.dateUpdated = dateUpdated;
}


public void setEntity_type(String entity_type) {
this.entity_type = entity_type;
}

public void setId(Long id) {
this.id = id;
}


public void setUpdatedByUser(String updatedByUser) {
this.updatedByUser = updatedByUser;
}

public void setVersion(Integer version) {
this.version = version;
}

}

@Entity
public class Consum extends Document{

String numarComanda;
String locConsum;
@ManyToOne
Gestiune gestiune;
}


@Entity
public class DocInsotitor extends Document {
private String mijlTransport;

@ManyToOne
private DocInsotitor docInsotitorStornat;

@ManyToOne
private DocInsotitor docInsotitorDeStornare;

@ManyToOne
private Furnizor furnizor;
Universitatea Alexandru Ioan Cuza din Iasi
Facultatea de Economie si Administrarea Afacerilor
An 3, Informatic Economic
Proiectarea Sistemelor Informationale

@OneToMany(mappedBy = "docInsotitor", cascade = CascadeType.ALL, fetch
= FetchType.EAGER)
private Set<Receptie> receptii = new HashSet<Receptie>();
}


@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Document extends AbstractEntity {

private String tipDocument;
private String numarDocument;
@Temporal(value = TemporalType.DATE)
private Date dataDocument;
@Temporal(value = TemporalType.TIMESTAMP)
private Date dataOperare;
@OneToMany(mappedBy = "document", cascade = CascadeType.ALL, fetch =
FetchType.EAGER)
private Set<LinieDocument> liniiDocument = new
HashSet<LinieDocument>();

}


@Entity
public class Furnizor extends AbstractEntity {

@Column(unique = true)
private String cod;
private String nume;
private String adresa;

private String CUI;
private String banca;
private String contBancar;
private Double sold;
@ManyToOne
private Localitate localitate;

}


@Entity
public class LinieDocument extends AbstractEntity {


Double cantitate=0.0; //valoarea null trebuie evitata cu orice pret
aici
Double pret=0.0; //valoarea null trebuie evitata cu orice pret aici
@ManyToOne
BunMaterial material;
@ManyToOne
Document document;

}

Universitatea Alexandru Ioan Cuza din Iasi
Facultatea de Economie si Administrarea Afacerilor
An 3, Informatic Economic
Proiectarea Sistemelor Informationale
public class Receptie extends Document{
@ManyToOne
DocInsotitor docInsotitor;
@ManyToOne
Gestiune gestiune;

Boolean facturaPrimita;

}

S-ar putea să vă placă și