lunedì 24 novembre 2014

Applicazioni Web Component-Based: Origami

Andrew Betts, direttore di FT Labs , ha presentato alla Velocity Europa 2014 assistenti di una serie di norme e strumenti di produzione propria per lo sviluppo web. Esse mirano a far fronte alle sfide dello sviluppo di creare e mantenere più di ottocento * .ft.com siti. FT Labs strategia principale è di pagine web suddivisione in componenti incorporati all'interno di un insieme ben definito di regole.

FT Labs è un Financial Times squadra incentrata sulle tecnologie web. La rapida crescita delle attività digitali Financial Times ha portato ad una serie di sfide, tutti legati in scala. Il gran numero di diversi siti web, senza, regole e strumenti strutturati comuni significa un sacco di lavoro ripetuto. Un sempre crescente, sempre più complessa rete ecosistema induce significativo trascinamento: difficile da mantenere ed evolvere applicazioni web; codice legacy che è impossibile da smantellare; contorti integrazioni applicative; difficile da trovare, i requisiti end-to-end competenze ingegneristiche.

Così FT Labs hanno cercato di trovare una soluzione che affronta questi problemi e si stabilirono su un approccio basato su componenti. Un insieme di principi sono alla base della soluzione. Alcuni di loro sono come segue:

Tutto dovrebbe essere disciplinato da norme
I componenti non devono essere speciale cased a un (ie sito web) singolo prodotto
I componenti dovrebbero essere facile da usare e non supponente
Consumatori componente dovrebbe controllare i tempi di aggiornamento dei componenti utilizzati
I componenti devono essere incapsulati o namespace in modo che non interferiscano con i loro "vicini web"
Dipendenze sui sistemi esterni dovrebbero essere ridotti al minimo, in modo che la soluzione globale è più affidabile e più veloce per spedire.
I componenti sono di due tipi: moduli e servizi web.



Un'applicazione costruita con componenti di Origami (originariamente pubblicato sul  Origami  sito web).

I moduli sono risorse statiche (ad esempio, file CSS) o CommonJS moduli, quindi il loro scopo principale è quello di fornire un'esperienza utente coerente su siti web. Ogni modulo deve seguire una specifica che tocca convenzioni di denominazione, il pacchetto e costruire configurazioni, i test e le regole demo, tra gli altri requisiti. Gli esempi includono o-grid , una griglia per i layout sensibili, o-date , per la formattazione della data e l'aggiornamento, oppure o-ft-tipografia , per specifici per il marchio stili tipografici FT. Documentazione Questi moduli 'mette in mostra ciò che è possibile, seguendo le specifiche.

Web Services, come dice il nome, fornisce contenuti e dati attraverso un endpoint URL. Servizi Web devono essere conformi ad un disciplinare . La specifica definisce una serie di requisiti, come ad esempio le regole di deprecazione, endpoint necessari (per controlli sanitari, metriche e documentazione), le regole di controllo delle versioni e dei molteplici servizi web ambienti regole. Il reattivo-image-proxy , un proxy per il ridimensionamento e l'ottimizzazione delle immagini, è un esempio di un servizio web Origami.

Origami fornisce un servizio di compilazione dei moduli. Il servizio di build è solitamente attivata in fase di esecuzione. Se una pagina web contiene <link> tag come questi:

<Link rel = href "stylesheet" = "// build.origami.ft.com/bundles/css?modules=o-ft-icons@^2.3.1" />
Il processo di compilazione sarà:

Installare la versione 2.3.1 (o aggiornamenti fino alla versione principale successiva) del o-ft-icons modulo
Installare tutte le sue dipendenze, se capita di avere qualsiasi
Eseguire il processo di compilazione
Minimizza l'uscita CSS
Gzip it & cache di esso
Servire con un CDN
C'è anche un processo di generazione Javascript equivalente che viene attivata tramite script di tag.

FT Labs fornisce di un componente registro che può essere utilizzato da chiunque, anche se alcuni componenti sono Financial Times-specifico, come abbiamo visto.

Andrew ha terminato il suo discorso presentando FT Labs polyfills as a Service . Polyfills è Javascript codice che aggiunge caratteristica non disponibile in modo nativo su un browser web, lisciando così le differenze tra venditori e versioni. Il servizio è personalizzabile , ma il suo utilizzo può essere semplice come includere questo tag script nella pagina web:

mercoledì 19 novembre 2014

Categorise progetti nel Package Explorer per ridurre l'ingombro in Eclipse

Se sei stato appeso su uno spazio di lavoro Eclipse per l'ultimo paio di anni, probabilmente avrete decine di progetti ingombrano il tuo spazio di lavoro. Se sei uno sviluppatore di Eclipse RCP, potrebbe essere seduto con circa 50+ progetti facilmente.

Il fatto è che spesso si lavora solo con 1 o 2 alla volta, non l'intero lotto. E a volte si desidera un modo conveniente di soli Visitano progetti appartenenti ad uno specifico prodotto / funzione / livello / qualsiasi-altra-gruppo-che-fa-senso. Avendo tutti i progetti in una lunga lista rende difficile da gestire e più difficili da navigare.

Ecco perché il Package Explorer e Gestione progetti hanno una bella caratteristica che riduce l'ingombro e consente di organizzare il vostro progetto in categorie che abbiano un senso. Così, invece di Explorer pacchetto cercando pesante e piatto come questo,



che potrebbe essere la seguente:



Se sei stato appeso su uno spazio di lavoro Eclipse per l'ultimo paio di anni, probabilmente avrete decine di progetti ingombrano il tuo spazio di lavoro. Se sei uno sviluppatore di Eclipse RCP, potrebbe essere seduto con circa 50+ progetti facilmente.

Il fatto è che spesso si lavora solo con 1 o 2 alla volta, non l'intero lotto. E a volte si desidera un modo conveniente di soli Visitano progetti appartenenti ad uno specifico prodotto / funzione / livello / qualsiasi-altra-gruppo-che-fa-senso. Avendo tutti i progetti in una lunga lista rende difficile da gestire e più difficili da navigare.

Ecco perché il Package Explorer e Gestione progetti hanno una bella caratteristica che riduce l'ingombro e consente di organizzare il vostro progetto in categorie che abbiano un senso. Così, invece di Explorer pacchetto cercando pesante e piatto come questo,



che potrebbe essere la seguente:




Pubblicità



Come classificare i progetti

Questa funzione lavora a stretto contatto con un altro elemento Eclipse chiamato working set. Un insieme di lavoro è solo un raggruppamento di risorse (es. File, cartelle e progetti). Ogni categoria è solo un insieme di lavoro.

Per classificare i progetti, faremo prima creiamo alcuni set di lavoro e quindi abilitare la funzione in Esplora Package.

Per creare un gruppo di lavoro effettuare le seguenti operazioni:

Aprire l'Explorer pacchetto (o Project Explorer) e nel menu View (triangolo nell'angolo in alto a destra), fare clic su Select Working set ...
Fare clic su Nuovo ... nella finestra di dialogo Seleziona working set.
Selezionare Resource tipo di set di lavoro e fare clic su Avanti.
Nella pagina successiva selezionare tutti i progetti che si desidera includere nel working set e scegliere un nome descrittivo per il set di lavoro. Ripetere la procedura per tutti gli altri gruppi di lavoro che si desidera.
Fare clic su Fine.
Ecco un esempio di ciò che la finestra di lavoro impostato dovrebbe essere simile:



Ora per attivare la funzione di raggruppamento. Aprire Visualizza il menu principale del Package Explorer di nuovo e consentire Top elementi di livello> working set . Se è la prima volta che si esegue questa operazione, Eclipse vi chiederà di configurare gruppi di lavoro - un modo per chiedere a voi che di lavoro Consente di visualizzare in Esplora Package. Seleziona tutti i gruppi di lavoro creati e fare clic su Ok.

Ora dovreste vedere i set di lavoro in Esplora package e se si espande esso, tutti i progetti selezionati sarà mostrato.

Ecco un breve video per darvi un esempio di come funziona e guarda. Nell'esempio, ci sono 8 progetti, 3 appartenenti alla UI e 3 per il modello. I gruppi di lavoro saranno raggrupparli in base alla UI e modello. Ci sono anche 2 progetti che sono i progetti d'appoggio, quindi per ora non saranno classificati.


Note:

Un progetto può appartenere al maggior numero di set di lavoro che si desidera , in modo che possa apparire in una serie di categorie.
È possibile scegliere quali gruppi di lavoro vengono visualizzati in Esplora Package scegliendo Configura lavoro Imposta ... dal menu Visualizza e quindi selezionando / deselezionando le relative working set. NB! Questa voce di menu non è disponibile se non siete nel layout working set.
Per tornare alla visualizzazione normale, selezionare Top elementi di livello> Progetti dal menu Visualizza.
Ogni progetto non assegnato a un set di lavoro va in una categoria chiamata Altri Progetti . Questo non è in realtà un insieme di lavoro, ma una categoria di default che Eclipse assegna ai progetti non assegnati di gruppo.
È possibile riordinare i set di lavoro trascinando ovunque.
I nuovi progetti possono rapidamente essere assegnati a gruppi di lavoro da una trascinandoli sul working set o tasto destro del mouse sul progetto e selezionare Assegna Working Set .
Limitazioni: Anche se i set di lavoro consentono di organizzare le risorse, tutte le nuove risorse non saranno automaticamente aggiunti ad un gruppo di lavoro, anche se il loro genitore appartiene già a quel set di lavoro . Nel nostro caso, questo significa che ogni nuovo progetto deve essere esplicitamente inserito in un insieme di lavoro, in caso contrario verrà visualizzato nella categoria Altri Progetti. Normalmente si può fare questo su procedure guidate Nuovo progetto, in modo da guardare fuori per questi.
Pubblicità


Alcuni buoni motivi per cui si dovrebbe classificare i vostri progetti

Ora che sapete come progetti di gruppo, si potrebbe chiedere perché si dovrebbe.

Beh, a parte solo guardando molto più pulito e meno denso, ma significa anche che si può agire su un gruppo di progetti alla volta. Ad esempio, è possibile fare clic destro su un lavoro impostato in Package Explorer e aprire, chiudere o aggiornare tutti i progetti in questo working set. Lo stesso vale per la squadra comandi (piacevoli per gli aggiornamenti selettivi).

Un altro motivo è che ora è possibile cercare in modo selettivo solo i progetti dicendo Eclipse di cercare solo determinati gruppi di lavoro. Ora non dovete far salire le occorrenze in progetti di prova o d'appoggio se non si desidera. Ci sono una miriade di altri comandi Eclipse che agiscono solo sui set di lavoro individuali (ad es. La costruzione, problemi, ecc).

E l'ultima ragione è che ora è molto più facile da navigare Explorer pacchetto con la tastiera. Un altro motivo per iniziare ad imparare le scorciatoie da tastiera Eclipse e anche impressionare i vostri colleghi.

giovedì 6 novembre 2014

Lascia il tuo codice di un Colpo di caffeina

La Zona mobile è presentato da Couchbase e Intel . Guarda come NoSQL DB pila quando scala di RAM e frequentare webinar gratuiti in C, C ++ e Fortran .
Originariamente scritto da Lauren Clapper
Quasi tutti i programmatori e gli sviluppatori almeno hanno una certa conoscenza di Java, ed è la lingua più frequentemente utilizzata per le applicazioni Android. L' indice TIOBE per Ottobre 2014 nomi Java come secondo linguaggio di programmazione più utilizzato su Internet. Quindi, se siete come me e ti piace lavorare nel modo più efficiente possibile, Percolate ha alcune notizie interessanti per voi.

Il 13 ottobre, Percolate ha annunciato la sua caffeina biblioteca Android. Percolato promesse che la biblioteca accelerare lo sviluppo di Android, come Java, nelle loro stesse parole, può essere molto "verbose". La caffeina promette di fare queste tre cose:

1. Shrink codebase
"Alcune attività che richiedono più righe di codice ora prendere solo uno, o forse due linee. A Percolate, usando questa libreria, abbiamo ridotto non solo il nostro codice di base, ma anche eliminato discreta quantità di duplicazione del codice. Questo segue il DRY, (abbreviazione di Do not Repeat Yourself), principio di sviluppo del software, che è una cosa molto buona per lottare per ".
2. Fornire una maggiore protezione contro codice Buggy
"Nel caso di applicazioni Android, scarsa gestione delle eccezioni può portare a buggy apps che si scontrano, che si traduce in una cattiva esperienza per gli utenti. La caffeina aiuta a risolvere questo fornendo molto spinto, ben recensito, e pesantemente testato codice che può essere utilizzato in parti critiche della vostra applicazione, in cui la gestione delle eccezioni in caso contrario può essere dimenticato. "
3. Essere parte di un progetto Open Source Famiglia
"Percolate ha sempre cercato di produzione di alta qualità, ricco di funzionalità software che è La Zona mobile è presentato da Couchbase e Intel . Guarda come NoSQL DB pila quando scala di RAM e frequentare webinar gratuiti in C, C ++ e Fortran .
Originariamente scritto da Lauren Clapper
Quasi tutti i programmatori e gli sviluppatori almeno hanno una certa conoscenza di Java, ed è la lingua più frequentemente utilizzata per le applicazioni Android. L' indice TIOBE per Ottobre 2014 nomi Java come secondo linguaggio di programmazione più utilizzato su Internet. Quindi, se siete come me e ti piace lavorare nel modo più efficiente possibile, Percolate ha alcune notizie interessanti per voi.

Il 13 ottobre, Percolate ha annunciato la sua caffeina biblioteca Android. Percolato promesse che la biblioteca accelerare lo sviluppo di Android, come Java, nelle loro stesse parole, può essere molto "verbose". La caffeina promette di fare queste tre cose:

1. Shrink codebase
"Alcune attività che richiedono più righe di codice ora prendere solo uno, o forse due linee. A Percolate, usando questa libreria, abbiamo ridotto non solo il nostro codice di base, ma anche eliminato discreta quantità di duplicazione del codice. Questo segue il DRY, (abbreviazione di Do not Repeat Yourself), principio di sviluppo del software, che è una cosa molto buona per lottare per ".
2. Fornire una maggiore protezione contro codice Buggy
"Nel caso di applicazioni Android, scarsa gestione delle eccezioni può portare a buggy apps che si scontrano, che si traduce in una cattiva esperienza per gli utenti. La caffeina aiuta a risolvere questo fornendo molto spinto, ben recensito, e pesantemente testato codice che può essere utilizzato in parti critiche della vostra applicazione, in cui la gestione delle eccezioni in caso contrario può essere dimenticato. "
3. Essere parte di un progetto Open Source Famiglia
"Percolate ha sempre cercato di produzione di alta qualità, ricco di funzionalità software che è divertente da usare. La caffeina è stata costruita con tali norme, così come lo erano gli altri strumenti open source:. Jennifer, jsonmatch, e redset "
Ad un primo sguardo, sembra che tutti i codici hanno un tema in comune: Il vostro tempo di codifica esaurito e sostenendo che il codice sarà notevolmente ridotta. Per esempio: di caffeina CountUtil codice contiene la formattazione dei numeri e scelte stilistiche, cioè si avrebbe 15k invece di 15.000.

Visualizza sorgentestampare ?
. 01
package com.percolate.caffeine;
02.

. 03
import java.text.DecimalFormat;
04.

05.
/ **
06.
* <h2> Metodi di utilità per il conteggio di formattazione </ h2>
07.
* <p />
. 08
* <h3> utilizza Comune: </ h3>
. 09
* CountUtil.{@link #getFormattedCount getFormattedCount} (1200000); // Restituisce "1,2 m"
10.

11.
* /
12.

13.
pubblica class CountUtil {
14.

15.
/ **
16.
*see #getFormattedCount (Long)
17.
* /
18.
pubblica static String getFormattedCount ( int count) {
. 19
ritorno getFormattedCount (Long.valueOf (conteggio));
20.
}
21.

22.
/ **
23.
*see #getFormattedCount (Long)
24.
* /
25.
pubblica static String getFormattedCount (conteggio String) {
. 26
ritorno getFormattedCount (Long.parseLong (conteggio));
27.
}
28.

29.
/ **
30.
* Consente di formattare un numero dato in una breve rappresentazione.
31.
* <p />
32.
* Esempi:
33.
* Dato 9100, tornerà "9.1k".
34.
* Dato 8.100.000, tornerà "8,1 milioni"
35.
* Dato 10, tornerà il 10 "
36.
*
37.
*param count valore da convertire.
38.
*return formattato valore (vedi esempi)
39.
* /
40.
pubblica static String getFormattedCount (Lungo) {
41.
def unità String;
42.
finale doppio DBL;
. 43
def formato DecimalFormat = nuovo DecimalFormat ( "# #." );
44.
se (count < 1000 ) {
. 45
ritorno format.format (count);
46.
​​} altrimenti se (count < 1000000 ) {
. 47
unità = "k" ;
. 48
DBL = contare / 1000.0 ;
49.
} altrimenti se (count < 1000000000 ) {
. 50
unità = "m" ;
. 51
DBL = conteggio / 1.000.000,0 ;
52.
} altrimenti {
. 53
unità = "b" ;
. 54
DBL = conteggio / 1000000000,0 ;
55.
}
. 56
ritorno format.format (dbl) + unità;
57.
}
58.
}


Vuoi verificare se la connettività del dispositivo? Utilizzare di caffeina PhoneUtils codice:

Visualizza sorgentestampare ?
. 01
package com.percolate.caffeine;
02.

03.
importazione android.content.Context;
. 04
importare android.net.ConnectivityManager;
. 05
importare android.net.NetworkInfo;
06.
importazione android.provider.Settings;
07.

08.
/ **
09.
* <h2> telefono comune metodi di utilità </ h2>
10.
* <p />
. 11
* <h3> utilizza Comune: </ h3>
12.
* PhoneUtils.{@link #isRotationEnabled isRotationEnabled} (questo);
13.

14.
* PhoneUtils.{@link #isNetworkAvailable isNetworkAvailable} (questo);
15.

16.
* PhoneUtils.{@link #isConnectedWifi isConnectedWifi} (questo);
17.

18.
* PhoneUtils.{@link #isConnectedMobile isConnectedMobile} (questo);
19.

20.
* /
21.
pubblica di classe PhoneUtils {
22.

23.
/ **
24.
* controlla se l'utente ha abilitato la rotazione / disattivato nelle impostazioni del telefono.
25.
*
26.
*param contesto Il contesto corrente o di attività che questo metodo viene chiamato da
27.
*return true se la rotazione è abilitata, altrimenti false.
28.
* /
29.
pubblica static boolean isRotationEnabled (Context context) {
. 30
ritorno android.provider.Settings.System.getInt (context.getContentResolver (), Settings.System.ACCELEROMETER_ROTATION, 0 ) == 1 ;
31.
}
32.

33.
/ **
34.
* controlla se il dispositivo è collegato a una rete (cellulare, wifi, ecc).
35.
*
36.
*param contesto Il contesto corrente o di attività che questo metodo viene chiamato da
37.
*return true se è disponibile una connessione di rete, in caso contrario false.
38.
* /
39.
pubblica static boolean isNetworkAvailable (Context context) {
40.
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService (Context.CONNECTIVITY_SERVICE);
41.
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo ();
. 42
ritorno activeNetworkInfo =! nullo && activeNetworkInfo.isConnected ();
43.
}
44.

45.
/ **
46.
​​* Verificare che non vi è alcuna connessione a una rete Wi-Fi.
47.
* <p />
48.
* Può essere usato in combinazione con {link #isConnectedMobile}
49.
* per fornire funzionalità diverse se il dispositivo si trova su una rete wifi o una rete cellulare.
50.
*
51.
*param contesto Il contesto corrente o di attività che questo metodo viene chiamato da
52.
*return true se è disponibile una connessione wi-fi, altrimenti false.
53.
* /
54.
pubblica static boolean isConnectedWifi (Context context) {
. 55
ConnectivityManager cm = (ConnectivityManager) context.getSystemService (Context.CONNECTIVITY_SERVICE);
. 56
informazioni NetworkInfo = cm.getActiveNetworkInfo ();
. 57
ritorno (info =! nullo && info.isConnected () && info.getType () == ConnectivityManager.TYPE_WIFI);
58.
}
59.

60.
/ **
61.
* Verificare che non vi è alcuna connessione a una rete mobile
62.
* <p />
63.
* Può essere usato in combinazione con {link #isConnectedWifi}
64.
* per fornire funzionalità diverse se il dispositivo si trova su una rete wifi o una rete cellulare.
65.
*
66.
*param contesto Il contesto corrente o di attività che questo metodo viene chiamato da
67.
*return true se è disponibile una connessione mobile, altrimenti false.
68.
* /
69.
pubblica static boolean isConnectedMobile (Context context) {
. 70
ConnectivityManager cm = (ConnectivityManager) context.getSystemService (Context.CONNECTIVITY_SERVICE);
. 71
informazioni NetworkInfo = cm.getActiveNetworkInfo ();
72.
ritorno (info =! nullo && info.isConnected () && info.getType () == ConnectivityManager.TYPE_MOBILE);
73.
}
74.

75.
}
Questi sono solo due esempi di codice caffeina, per gentile concessione di GitHub . Come si può utilizzare la caffeina per ottimizzare il vostro sviluppo?La Zona mobile è presentato da Couchbase e Intel . Guarda come NoSQL DB pila quando scala di RAM e frequentare webinar gratuiti in C, C ++ e Fortran .
Originariamente scritto da Lauren Clapper
Quasi tutti i programmatori e gli sviluppatori almeno hanno una certa conoscenza di Java, ed è la lingua più frequentemente utilizzata per le applicazioni Android. L' indice TIOBE per Ottobre 2014 nomi Java come secondo linguaggio di programmazione più utilizzato su Internet. Quindi, se siete come me e ti piace lavorare nel modo più efficiente possibile, Percolate ha alcune notizie interessanti per voi.

Il 13 ottobre, Percolate ha annunciato la sua caffeina biblioteca Android. Percolato promesse che la biblioteca accelerare lo sviluppo di Android, come Java, nelle loro stesse parole, può essere molto "verbose". La caffeina promette di fare queste tre cose:

1. Shrink codebase
"Alcune attività che richiedono più righe di codice ora prendere solo uno, o forse due linee. A Percolate, usando questa libreria, abbiamo ridotto non solo il nostro codice di base, ma anche eliminato discreta quantità di duplicazione del codice. Questo segue il DRY, (abbreviazione di Do not Repeat Yourself), principio di sviluppo del software, che è una cosa molto buona per lottare per ".
2. Fornire una maggiore protezione contro codice Buggy
"Nel caso di applicazioni Android, scarsa gestione delle eccezioni può portare a buggy apps che si scontrano, che si traduce in una cattiva esperienza per gli utenti. La caffeina aiuta a risolvere questo fornendo molto spinto, ben recensito, e pesantemente testato codice che può essere utilizzato in parti critiche della vostra applicazione, in cui la gestione delle eccezioni in caso contrario può essere dimenticato. "
3. Essere parte di un progetto Open Source Famiglia
"Percolate ha sempre cercato di produzione di alta qualità, ricco di funzionalità software che è divertente da usare. La caffeina è stata costruita con tali norme, così come lo erano gli altri strumenti open source:. Jennifer, jsonmatch, e redset "
Ad un primo sguardo, sembra che tutti i codici hanno un tema in comune: Il vostro tempo di codifica esaurito e sostenendo che il codice sarà notevolmente ridotta. Per esempio: di caffeina CountUtil codice contiene la formattazione dei numeri e scelte stilistiche, cioè si avrebbe 15k invece di 15.000.

Visualizza sorgentestampare ?
. 01
package com.percolate.caffeine;
02.

. 03
import java.text.DecimalFormat;
04.

05.
/ **
06.
* <h2> Metodi di utilità per il conteggio di formattazione </ h2>
07.
* <p />
. 08
* <h3> utilizza Comune: </ h3>
. 09
* CountUtil.{@link #getFormattedCount getFormattedCount} (1200000); // Restituisce "1,2 m"
10.

11.
* /
12.

13.
pubblica class CountUtil {
14.

15.
/ **
16.
*see #getFormattedCount (Long)
17.
* /
18.
pubblica static String getFormattedCount ( int count) {
. 19
ritorno getFormattedCount (Long.valueOf (conteggio));
20.
}
21.

22.
/ **
23.
*see #getFormattedCount (Long)
24.
* /
25.
pubblica static String getFormattedCount (conteggio String) {
. 26
ritorno getFormattedCount (Long.parseLong (conteggio));
27.
}
28.

29.
/ **
30.
* Consente di formattare un numero dato in una breve rappresentazione.
31.
* <p />
32.
* Esempi:
33.
* Dato 9100, tornerà "9.1k".
34.
* Dato 8.100.000, tornerà "8,1 milioni"
35.
* Dato 10, tornerà il 10 "
36.
*
37.
*param count valore da convertire.
38.
*return formattato valore (vedi esempi)
39.
* /
40.
pubblica static String getFormattedCount (Lungo) {
41.
def unità String;
42.
finale doppio DBL;
. 43
def formato DecimalFormat = nuovo DecimalFormat ( "# #." );
44.
se (count < 1000 ) {
. 45
ritorno format.format (count);
46.
​​} altrimenti se (count < 1000000 ) {
. 47
unità = "k" ;
. 48
DBL = contare / 1000.0 ;
49.
} altrimenti se (count < 1000000000 ) {
. 50
unità = "m" ;
. 51
DBL = conteggio / 1.000.000,0 ;
52.
} altrimenti {
. 53
unità = "b" ;
. 54
DBL = conteggio / 1000000000,0 ;
55.
}
. 56
ritorno format.format (dbl) + unità;
57.
}
58.
}


Vuoi verificare se la connettività del dispositivo? Utilizzare di caffeina PhoneUtils codice:

Visualizza sorgentestampare ?
. 01
package com.percolate.caffeine;
02.

03.
importazione android.content.Context;
. 04
importare android.net.ConnectivityManager;
. 05
importare android.net.NetworkInfo;
06.
importazione android.provider.Settings;
07.

08.
/ **
09.
* <h2> telefono comune metodi di utilità </ h2>
10.
* <p />
. 11
* <h3> utilizza Comune: </ h3>
12.
* PhoneUtils.{@link #isRotationEnabled isRotationEnabled} (questo);
13.

14.
* PhoneUtils.{@link #isNetworkAvailable isNetworkAvailable} (questo);
15.

16.
* PhoneUtils.{@link #isConnectedWifi isConnectedWifi} (questo);
17.

18.
* PhoneUtils.{@link #isConnectedMobile isConnectedMobile} (questo);
19.

20.
* /
21.
pubblica di classe PhoneUtils {
22.

23.
/ **
24.
* controlla se l'utente ha abilitato la rotazione / disattivato nelle impostazioni del telefono.
25.
*
26.
*param contesto Il contesto corrente o di attività che questo metodo viene chiamato da
27.
*return true se la rotazione è abilitata, altrimenti false.
28.
* /
29.
pubblica static boolean isRotationEnabled (Context context) {
. 30
ritorno android.provider.Settings.System.getInt (context.getContentResolver (), Settings.System.ACCELEROMETER_ROTATION, 0 ) == 1 ;
31.
}
32.

33.
/ **
34.
* controlla se il dispositivo è collegato a una rete (cellulare, wifi, ecc).
35.
*
36.
*param contesto Il contesto corrente o di attività che questo metodo viene chiamato da
37.
*return true se è disponibile una connessione di rete, in caso contrario false.
38.
* /
39.
pubblica static boolean isNetworkAvailable (Context context) {
40.
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService (Context.CONNECTIVITY_SERVICE);
41.
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo ();
. 42
ritorno activeNetworkInfo =! nullo && activeNetworkInfo.isConnected ();
43.
}
44.

45.
/ **
46.
​​* Verificare che non vi è alcuna connessione a una rete Wi-Fi.
47.
* <p />
48.
* Può essere usato in combinazione con {link #isConnectedMobile}
49.
* per fornire funzionalità diverse se il dispositivo si trova su una rete wifi o una rete cellulare.
50.
*
51.
*param contesto Il contesto corrente o di attività che questo metodo viene chiamato da
52.
*return true se è disponibile una connessione wi-fi, altrimenti false.
53.
* /
54.
pubblica static boolean isConnectedWifi (Context context) {
. 55
ConnectivityManager cm = (ConnectivityManager) context.getSystemService (Context.CONNECTIVITY_SERVICE);
. 56
informazioni NetworkInfo = cm.getActiveNetworkInfo ();
. 57
ritorno (info =! nullo && info.isConnected () && info.getType () == ConnectivityManager.TYPE_WIFI);
58.
}
59.

60.
/ **
61.
* Verificare che non vi è alcuna connessione a una rete mobile
62.
* <p />
63.
* Può essere usato in combinazione con {link #isConnectedWifi}
64.
* per fornire funzionalità diverse se il dispositivo si trova su una rete wifi o una rete cellulare.
65.
*
66.
*param contesto Il contesto corrente o di attività che questo metodo viene chiamato da
67.
*return true se è disponibile una connessione mobile, altrimenti false.
68.
* /
69.
pubblica static boolean isConnectedMobile (Context context) {
. 70
ConnectivityManager cm = (ConnectivityManager) context.getSystemService (Context.CONNECTIVITY_SERVICE);
. 71
informazioni NetworkInfo = cm.getActiveNetworkInfo ();
72.
ritorno (info =! nullo && info.isConnected () && info.getType () == ConnectivityManager.TYPE_MOBILE);
73.
}
74.

75.
}
Questi sono solo due esempi di codice caffeina, per gentile concessione di GitHub . Come si può utilizzare la caffeina per ottimizzare il vostro sviluppo?

lunedì 3 novembre 2014

Ibernazione Le Collezioni blocco ottimistico

Hibernate fornisce un  meccanismo di blocco ottimistico  per prevenire  aggiornamenti persi  anche per-lunghe conversazioni. In combinazione con una memoria entità, si estende su più richieste degli utenti (contesto di persistenza esteso o entità indipendenti) Hibernate può garantire  a livello di applicazione ripetibile-legge .

Il  meccanismo di controllo sporca  entità rileva i cambiamenti di stato e incrementa la versione entità. Mentre le modifiche alle proprietà di base sono sempre presi in considerazione, le collezioni Hibernate sono più sottili in questo senso.

Di proprietà vs collezioni Inverse
Nei database relazionali, due record sono associati con un riferimento chiave esterna. In questo rapporto, il record si fa riferimento è il genitore, mentre la riga di riferimento (il lato chiave esterna) è il bambino. Una chiave esterna non nullo può fare riferimento solo a un record principale esistente.

Nello spazio a oggetti questa associazione può essere rappresentato in entrambe le direzioni. Possiamo avere un riferimento molti-a-uno da un bambino genitore e il genitore può anche avere una collezione uno-a-molti bambini.

Poiché entrambe le parti potrebbero potenzialmente controllare lo stato chiave esterna banca dati, dobbiamo fare in modo che solo una parte è il proprietario di questa associazione. Solo i  titolari di cambiamenti di stato laterali vengono propagate al database. Il lato non possessore è stato tradizionalmente definito come l'  inverso  lato.

Successivo vi descriverò i modi più comuni di modellazione questa associazione.

Il-madre che detiene-side-bambino associazione mappatura unidirezionale
Solo il lato genitore ha un  OneToMany  bambini non inversa raccolta. L'entità bambino non fa riferimento alla controllante a tutti.

Visualizza sorgentestampare ?
1.
Entity (name = "post" )
2.
pubblico class post {
3.
...
4.
OneToMany (cascade = CascadeType.ALL, orphanRemoval = true )
. 5
private List <Commento> commenti = nuovo ArrayList <Commento> ();
6.
...
7.
}
Il-madre che detiene-side-bambino associazione componente mappatura mappatura unidirezionale
Il lato bambino non sempre deve essere una entità e potremmo modellare come un tipo di componente  , invece. Un  integrabile  oggetto (tipo di componente) può contenere entrambi i tipi di base e le mappature di associazione, ma non può mai contenere unId. L'oggetto è integrabile persistente / rimosso insieme alla sua entità possedere.

Il genitore ha un  ElementCollection  associazione bambini. L'entità bambino può fare riferimento solo il genitore attraverso la non-interrogabile Sospensione specifico  Parent annotazione.

Visualizza sorgentestampare ?
01.
Entity (name = "post" )
02.
pubblica class post {
03.
...
04.
ElementCollection
05.
JoinTable (nome = "post_comments" , joinColumns = JoinColumn (name = "post_id" ))
06.
OrderColumn (name = "comment_index" )
. 07
private List <Commento> commenti = nuovo ArrayList <Commento> ();
08.
...
09.

10.
pubblico vuoto addComment (commento commenti) {
. 11
comment.setPost ( questo );
. 12
comments.add (commento);
13.
}
14.
}
15.

16.
Embeddable
17.
pubblica class {Commento
18.
...
19.
Parent
20.
privato annuncio Pubblica;
21.
...
22.
}
Il-madre che detiene-side-bambino associazione mappatura bidirezionale
Il genitore è il lato proprietaria quindi ha un  OneToMany  non inversa (senza una direttiva mappedBy) figli di raccolta. L'entità bambino fa riferimento alla controllante attraverso un  ManyToOne  associazione che è né inseribile né aggiornabile:

Visualizza sorgentestampare ?
01.
Entity (name = "post" )
02.
pubblica class post {
03.
...
04.
OneToMany (cascade = CascadeType.ALL, orphanRemoval = true )
. 05
private List <Commento> commenti = nuovo ArrayList <Commento> ();
06.
...
07.

08.
pubblico vuoto addComment (commento commenti) {
. 09
comment.setPost ( questo );
. 10
comments.add (commento);
11.
}
12.
}
13.

14.
Entity (name = "commenti" )
15.
pubblica di classe Commento
16.
...
17.
ManyToOne
18.
JoinColumn (name = "post_id" , inseribile = falso , aggiornabile = falso )
19.
privato annuncio Pubblica;
20.
...
21.
}
Il figlio possedere-side-genitore associazione mappatura bidirezionale
L'entità bambino fa riferimento alla controllante attraverso un  ManyToOne  associazione, e il genitore ha un  mappedBy  OneToMany  bambini collezione. La parte principale è il lato inverso in modo che solo iManyToOne cambiamenti di stato vengono propagate al database.

Anche se c'è solo una parte proprietaria, è sempre una buona norma  tenere entrambe le parti in sincronia  utilizzando l'add / removeChild (metodi).

Visualizza sorgentestampare ?
01.
Entity (name = "post" )
02.
pubblica class post {
03.
...
04.
OneToMany (cascade = CascadeType.ALL, orphanRemoval = true , mappedBy = "post" )
. 05
private List <Commento> commenti = nuovo ArrayList <Commento> ();
06.
...
07.
pubblico vuoto addComment (commento commenti) {
. 08
comment.setPost ( questo );
. 09
comments.add (commento);
10.
}
11.
}
12.

13.
Entity (name = "commenti" )
14.
pubblica class {Commento
15.
...
16.
ManyToOne
17.
privato annuncio Pubblica;
18.
...
19.
}
Il figlio possedere-side-genitore associazione mappatura unidirezionale
L'entità bambino fa riferimento il genitore attraverso un  ManyToOne  associazione. Il genitore non ha una  OneToMany  bambini insieme in modo che il soggetto bambino diventa il lato di appartenenza. Questa mappatura associazione ricorda i dati relazionali linkage chiave esterna.

Visualizza sorgentestampare ?
1.
Entity (name = "commenti" )
2.
pubblico class {Commento
3.
...
4.
ManyToOne
5.
privato annuncio Pubblica;
6.
...
7.
}
Raccolta delle versioni
La sezione 3.4.2 della  specifica JPA 2.1  definisce il blocco ottimistico come:

L'attributo versione viene aggiornata dal runtime provider di persistenza quando l'oggetto viene scritto nel database. Tutti i campi non di relazione e cravatte propri e tutti i rapporti di proprietà del soggetto sono compresi nel controllo di versione [35].

[35] Ciò comprende i rapporti di proprietà mantenuti in uniscono tabelle

NB Solo i bambini collezione possedere-side in grado di aggiornare la versione del genitore.

Tempo di analisi
Testiamo come il tipo di associazione genitore-bambino influisce sul controllo delle versioni genitore. Poiché siamo interessati al controllo collezione bambini sporchi, il figlio possedere-side-genitore unidirezionale  associazione sta per saltare, come in questo caso il genitore non contiene una collezione per bambini.

Banco di prova
Il seguente banco di prova sta per essere utilizzato per tutti i casi d'uso di tipo di raccolta:

Visualizza sorgentestampare ?
01.
protette vuoto simulateConcurrentTransactions ( finale boolean shouldIncrementParentVersion) {
02.
def ExecutorService ExecutorService = Executors.newSingleThreadExecutor ();
03.

04.
doInTransaction ( nuovo TransactionCallable <Vuoto> () {
05.
Override
06.
pubblica Void execute (Session session) {
07.
provare {
. 08
P post = postClass.newInstance ();
09.
post.setId (1L);
10.
post.setName ( "Sospensione di formazione" );
. 11
session.persist (post);
. 12
ritorno nullo ;
13.
} fermo (Exception e) {
. 14
gettare nuova IllegalArgumentException (e);
15.
}
16.
}
17.
});
18.

19.
doInTransaction ( nuovo TransactionCallable <Vuoto> () {
20.
Override
21.
pubblica Void execute ( finale Session session) {
. 22
def post = P (P) session.get (postClass, 1L);
23.
provare {
24.
executorService.submit ( nuovo Callable <Vuoto> () {
25.
Override
26.
pubblica chiamata Void () lancia Exception {
27.
ritorno doInTransaction ( nuovo TransactionCallable <Vuoto> () {
28.
Override
29.
pubblica Void execute (_SESSION Session) {
30.
provare {
31.
P otherThreadPost = (P) _session.get (postClass, 1L);
32.
int loadTimeVersion = otherThreadPost.getVersion ();
33.
assertNotSame (post, otherThreadPost);
. 34
assertEquals (0L, otherThreadPost.getVersion ());
. 35
C comment = commentClass.newInstance ();
36.
comment.setReview ( "Buon posto!" );
37.
otherThreadPost.addComment (commento);
. 38
_session.flush ();
39.
se (shouldIncrementParentVersion) {
. 40
assertEquals (otherThreadPost.getVersion (), loadTimeVersion + 1 );
41.
} altrimenti {
. 42
assertEquals (otherThreadPost.getVersion (), loadTimeVersion);
43.
}
. 44
ritorno nullo ;
45.
} fermo (Exception e) {
. 46
gettare nuova IllegalArgumentException (e);
47.
}
48.
}
49.
});
50.
}
. 51
.}) get ();
52.
} fermo (Exception e) {
. 53
gettare nuova IllegalArgumentException (e);
54.
}
. 55
post.setName ( "Sospensione Master Class" );
. 56
session.flush ();
. 57
ritorno nullo ;
58.
}
59.
});
60.
}
Il test di associazione-madre che detiene-side-bambino unidirezionale

Visualizza sorgentestampare ?
01.
tabelle #create
02.
Domanda: {[creare commento della tabella (idbigint generato da impostazione predefinita come identità (iniziare con 1 ), recensione varchar ( 255 ), chiave primaria (id))] []}
03.
Domanda: {[create table posta (non idbigint nullo , nome varchar ( 255 ), la versione numero intero non nullo , chiave primaria (id))] []}
04.
Domanda: {[create table post_comment (post_id bigint non nullo , bigint comments_id non nullo , comment_index intero non nullo , chiave primaria (post_id, comment_index))] []}
05.
Domanda: {[alter table post_comment aggiungere vincolo di chiave esterna FK_se9l149iyyao6va95afioxsrl (comments_id) riferimenti commento] []}
06.
Domanda: {[alter table post_comment aggiungere vincolo di chiave esterna FK_6o1igdm04v78cwqre59or1yj1 (post_id) riferimenti post] []}
07.

08.
posto #insert transazione primaria
09.
Domanda: {[(???,,) inserire in valori postale (nome, versione, id)] [formazione Hibernate, 0 , 1 ]}
10.

11.
posto #SELECT transazione secondaria
12.
Domanda: {[? selectentityopti0_.idas id1_1_0_, entityopti0_.name come name2_1_0_, entityopti0_.version come version3_1_0_ dal post entityopti0_ dove entityopti0_.id =] [ 1 ]}
13.

14.
commento #insert transazione secondaria
15.
aggiornamento di bloccaggio #optimistic versione post in un'operazione secondaria
16.
Domanda: {[inserire nel commento (id, recensione) valori ( di default ,?)] [buon posto!]}
. 17
Domanda: {[update dopo setName = ?, version =? dove id =? e la versione =?] [Hibernate formazione, 1 , 1 , 0 ]}
18.
Domanda: {[inserire in valori post_comment (post_id, comment_index, comments_id) (,,???)] [ 1 , 0 , 1 ]}
19.

20.
eccezione di bloccaggio #optimistic transazione primaria
. 21
Domanda: {[update dopo setName = ?, version =? dove id =? e la versione =?] [Hibernate Master Class, 1 , 1 , 0 ]}
22.
org.hibernate.StaleObjectStateException: Riga è stato aggiornato o cancellato da un'altra transazione (o mappatura unsaved-value non è corretta): [com.vladmihalcea.hibernate.masterclass.laboratory.concurrency.EntityOptimisticLockingOnUnidirectionalCollectionTest$Post# 1 ]
Il-madre che detiene-side-bambino test di associazione componente unidirezionale
Visualizza sorgentestampare ?
01.
tabelle #create
02.
Domanda: {[create table posta (non idbigint nullo , nome varchar ( 255 ), la versione numero intero non nullo , chiave primaria (id))] []}
03.
Domanda: {[creare post_comments tavolo (post_id bigint non nulli , recensione varchar ( 255 ), numero intero comment_index non nullo chiave, primaria (post_id, comment_index))] []}
04.
Domanda: {[alterare post_comments table Aggiungi vincolo di chiave esterna FK_gh9apqeduab8cs0ohcq1dgukp (post_id) riferimenti post] []}
05.

06.
posto #insert transazione primaria
07.
Domanda: {[(???,,) inserire in valori postale (nome, versione, id)] [formazione Hibernate, 0 , 1 ]}
08.

09.
posto #SELECT transazione secondaria
10.
Domanda: {[? selectentityopti0_.idas id1_0_0_, entityopti0_.name come name2_0_0_, entityopti0_.version come version3_0_0_ dal post entityopti0_ dove entityopti0_.id =] [ 1 ]}
11.
Domanda: {[? selectcomments0_.post_id come post_id1_0_0_, comments0_.review come review2_1_0_, comments0_.comment_index come comment_3_0_ da post_comments comments0_ dove comments0_.post_id =] [ 1 ]}
12.

13.
commento #insert transazione secondaria
14.
aggiornamento di bloccaggio #optimistic versione post in un'operazione secondaria
. 15
Domanda: {[update dopo setName = ?, version =? dove id =? e la versione =?] [Hibernate formazione, 1 , 1 , 0 ]}
16.
Domanda: {[inserire in post_comments (post_id, comment_index, revisione) valori (,,???)] [ 1 , 0 , buon post!]}
17.

18.
eccezione di bloccaggio #optimistic transazione primaria
. 19
Domanda: {[update dopo setName = ?, version =? dove id =? e la versione =?] [Hibernate Master Class, 1 , 1 , 0 ]}
20.
org.hibernate.StaleObjectStateException: Riga è stato aggiornato o cancellato da un'altra transazione (o mappatura unsaved-value non è corretta): [com.vladmihalcea.hibernate.masterclass.laboratory.concurrency.EntityOptimisticLockingOnComponentCollectionTest$Post# 1 ]
Il test di associazione-madre che detiene-side-bambino bidirezionale
Visualizza sorgentestampare ?
01.
tabelle #create
02.
Domanda: {[creare commento della tabella (idbigint generato da impostazione predefinita come identità (iniziare con 1 ), recensione varchar ( 255 ), bigint post_id chiave primaria, (id))] []}
03.
Domanda: {[create table posta (non idbigint nullo , nome varchar ( 255 ), la versione numero intero non nullo , chiave primaria (id))] []}
04.
Domanda: {[create table post_comment (post_id bigint non nullo , bigint comments_id non nullo )] []}
05.
Domanda: {[alter table post_comment aggiungere vincolo UK_se9l149iyyao6va95afioxsrl unico (comments_id)] ​​[]}
06.
Domanda: {[alter table vincolo commento aggiuntivo FK_f1sl0xkd2lucs7bve3ktt3tu5 chiave esterna (post_id) riferimenti post] []}
07.
Domanda: {[alter table post_comment aggiungere vincolo di chiave esterna FK_se9l149iyyao6va95afioxsrl (comments_id) riferimenti commento] []}
08.
Domanda: {[alter table post_comment aggiungere vincolo di chiave esterna FK_6o1igdm04v78cwqre59or1yj1 (post_id) riferimenti post] []}
09.

10.
posto #insert transazione primaria
11.
Domanda: {[(???,,) inserire in valori postale (nome, versione, id)] [formazione Hibernate, 0 , 1 ]}
12.

13.
posto #SELECT transazione secondaria
14.
Domanda: {[? selectentityopti0_.idas id1_1_0_, entityopti0_.name come name2_1_0_, entityopti0_.version come version3_1_0_ dal post entityopti0_ dove entityopti0_.id =] [ 1 ]}
15.
Domanda: {[selectcomments0_.post_id come post_id1_1_0_, comments0_.comments_id come comments2_2_0_, entityopti1_.idas id1_0_1_, entityopti1_.post_id come post_id3_0_1_, entityopti1_.review come review2_0_1_, entityopti2_.idas id1_1_2_, entityopti2_.name come name2_1_2_, entityopti2_.version come version3_1_2_ da post_comment comments0_ entityopti1_ joincomment interno su comments0_.comments_id = entityopti1_.idleft esterno joinpost entityopti2_ su entityopti1_.post_id = entityopti2_.idwhere comments0_.post_id =?] [ 1 ]}
16.

17.
commento #insert transazione secondaria
18.
aggiornamento di bloccaggio #optimistic versione post in un'operazione secondaria
19.
Domanda: {[inserire nel commento (id, recensione) valori ( di default ,?)] [buon posto!]}
. 20
Domanda: {[update dopo setName = ?, version =? dove id =? e la versione =?] [Hibernate formazione, 1 , 1 , 0 ]}
21.
Domanda: {[inserire in valori post_comment (post_id, comments_id) (,??)] [ 1 , 1 ]}
22.

23.
eccezione di bloccaggio #optimistic transazione primaria
. 24
Domanda: {[update dopo setName = ?, version =? dove id =? e la versione =?] [Hibernate Master Class, 1 , 1 , 0 ]}
25.
org.hibernate.StaleObjectStateException: Riga è stato aggiornato o cancellato da un'altra transazione (o mappatura unsaved-value non è corretta): [com.vladmihalcea.hibernate.masterclass.laboratory.concurrency.EntityOptimisticLockingOnBidirectionalParentOwningCollectionTest$Post# 1 ]
Il test di associazione-bambino possedere-side-genitore bidirezionale
Visualizza sorgentestampare ?
01.
tabelle #create
02.
Domanda: {[creare commento della tabella (idbigint generato da impostazione predefinita come identità (iniziare con 1 ), recensione varchar ( 255 ), bigint post_id chiave primaria, (id))] []}
03.
Domanda: {[create table posta (non idbigint nullo , nome varchar ( 255 ), la versione numero intero non nullo , chiave primaria (id))] []}
04.
Domanda: {[alter table vincolo commento aggiuntivo FK_f1sl0xkd2lucs7bve3ktt3tu5 chiave esterna (post_id) riferimenti post] []}
05.

06.
posto #insert transazione primaria
07.
Domanda: {[(???,,) inserire in valori postale (nome, versione, id)] [formazione Hibernate, 0 , 1 ]}
08.

09.
posto #SELECT transazione secondaria
10.
Domanda: {[? selectentityopti0_.idas id1_1_0_, entityopti0_.name come name2_1_0_, entityopti0_.version come version3_1_0_ dal post entityopti0_ dove entityopti0_.id =] [ 1 ]}
11.

12.
commento #insert transazione secondaria
13.
Versione #post non viene incrementato in un'operazione secondaria
14.
Domanda: {[inserire in valori commento (id, post_id, recensione) ( impostazione predefinita ,,??)] [ 1 , buon post!]}
15.
Domanda: {[? selectcount (id) da un commento in cui post_id =] [ 1 ]}
16.

17.
#update lavora a operazione primaria
. 18
Domanda: {[update dopo setName = ?, version =? dove id =? e la versione =?] [Hibernate Master Class, 1 , 1 , 0 ]}
Non tener conto di raccolta delle versioni di default
Se il valore di default che possiede sul lato raccolta delle versioni non è adatto per il vostro caso d'uso, è sempre possibile non tener conto con Hibernate [a href = "http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/ # d0e2903 "style =" font-family: inherit; font-size: 14px; font-style: inherit; font-weight: inherit; text-decoration: none; color: rgb (1, 160, 219); -webkit- tap-highlight-color: rgb (240, 29, 79); sfondo: trasparente; "] @ OptimisticLock annotazione.

Cerchiamo di non tener conto del meccanismo di versione di aggiornamento genitore predefinito per  bidirezionale associazione-madre che detiene-lato-bambino :

Visualizza sorgentestampare ?
01.
Entity (name = "post" )
02.
pubblica class post {
03.
...
04.
OneToMany (cascade = CascadeType.ALL, orphanRemoval = true )
05.
OptimisticLock (escluso = true )
. 06
private List <Commento> commenti = nuovo ArrayList <Commento> ();
07.
...
08.

09.
pubblico vuoto addComment (commento commenti) {
. 10
comment.setPost ( questo );
. 11
comments.add (commento);
12.
}
13.
}
14.

15.
Entity (name = "commenti" )
16.
pubblica class {Commento
17.
...
18.
ManyToOne
19.
JoinColumn (name = "post_id" , inseribile = falso , aggiornabile = falso )
20.
privato annuncio Pubblica;
21.
...
22.
}
Questa volta, i cambiamenti di raccolta i bambini non si innescherà un aggiornamento di versione genitore:

Visualizza sorgentestampare ?
01.
tabelle #create
02.
Domanda: {[creare commento della tabella (idbigint generato da impostazione predefinita come identità (iniziare con 1 ), recensione varchar ( 255 ), bigint post_id chiave primaria, (id))] []}
03.
Domanda: {[create table posta (non idbigint nullo , nome varchar ( 255 ), la versione numero intero non nullo , chiave primaria (id))] []}
04.
Domanda: {[create table post_comment (post_id bigint non nullo , bigint comments_id non nullo )] []}
05.
Domanda: {[]}
06.
Domanda: {[alter table vincolo commento aggiuntivo FK_f1sl0xkd2lucs7bve3ktt3tu5 chiave esterna (post_id) riferimenti post] []}
07.
Domanda: {[alter table post_comment aggiungere vincolo di chiave esterna FK_se9l149iyyao6va95afioxsrl (comments_id) riferimenti commento] []}
08.
Domanda: {[alter table post_comment aggiungere vincolo di chiave esterna FK_6o1igdm04v78cwqre59or1yj1 (post_id) riferimenti post] []}
09.

10.
posto #insert transazione primaria
11.
Domanda: {[(???,,) inserire in valori postale (nome, versione, id)] [formazione Hibernate, 0 , 1 ]}
12.

13.
posto #SELECT transazione secondaria
14.
Domanda: {[? selectentityopti0_.idas id1_1_0_, entityopti0_.name come name2_1_0_, entityopti0_.version come version3_1_0_ dal post entityopti0_ dove entityopti0_.id =] [ 1 ]}
15.
Domanda: {[selectcomments0_.post_id come post_id1_1_0_, comments0_.comments_id come comments2_2_0_, entityopti1_.idas id1_0_1_, entityopti1_.post_id come post_id3_0_1_, entityopti1_.review come review2_0_1_, entityopti2_.idas id1_1_2_, entityopti2_.name come name2_1_2_, entityopti2_.version come version3_1_2_ da post_comment comments0_ entityopti1_ joincomment interno su comments0_.comments_id = entityopti1_.idleft esterno joinpost entityopti2_ su entityopti1_.post_id = entityopti2_.idwhere comments0_.post_id =?] [ 1 ]}
16.

17.
commento #insert transazione secondaria
18.
Domanda: {[inserire nel commento (id, recensione) valori ( di default ,?)] [buon posto!]}
19.
Domanda: {[inserire in valori post_comment (post_id, comments_id) (,??)] [ 1 , 1 ]}
20.

21.
#update lavora a operazione primaria
. 22
Domanda: {[update dopo setName = ?, version =? dove id =? e la versione =?] [Hibernate Master Class, 1 , 1 , 0 ]}
Conclusione
E 'molto importante capire come le varie strutture di modellazione modelli di concorrenza impatto. Le collezioni possedere lato modifiche vengono presi in considerazione per incrementare il numero di versione principale, e si può sempre bypassare utilizzando l'  OptimisticLock   annotazione.

Codice disponibile su  GitHub .

Se avete goduto la lettura del mio articolo e state cercando l'ora di arrivare notifiche e-mail istantanee dei miei ultimi messaggi, non vi resta che seguire il mio blog .