Loading...
donstany avatar donstany 5 Точки

[Course Project] Генериране на ID в entity клас при работа с RDBMS ORACLE 11

Здравейте,

Колеги мисля, че всеки ще срещне проблема с автоматичното генериране на ID (PK) в определена таблица. В Oracle 11 няма "autoincrement" индекс,  за разлика от следващата му версия.

След защитата на колегата днес се оказа, че има и по-чист вариант за генерирането му освен да се пише sql за вземане на последния индекс директно от базата.  Видях две решения и не знам коя е по-добрата практика.

Има и трето решение със sql, но не знам как да го ползвам в entity класа.

Sequence Strategy:

@Entity
 
@SequenceGenerator(name="seq", initialValue=1, allocationSize=10000)
public class EntityWithSequenceId {
    // Use the sequence that is defined above:
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="seq")
    @Id long id;
}

Table Strategy:

@Entity
@TableGenerator(name="tab", initialValue=0, allocationSize=50)
public class EntityWithTableId {
    @GeneratedValue(strategy=GenerationType.TABLE, generator="tab")
    @Id long id;
}

Има и един вариант директно да се напише в базата следния sql за създаване на поредица :

CREATE SEQUENCE emp_sequence
      INCREMENT BY 1
      START WITH 1
      NOMAXVALUE
      NOCYCLE
      CACHE 10;
Тагове:
2
Java Web Development
slancer avatar slancer 6 Точки

Здравей,

благодаря за информацията.

Доколкото разбрах и двата подхода се използват. Като мисля, че последния SQL код (изпълнен за базата чрез SQL Developer например) се използва в комбинация със Sequence Strategy (annotations/XML configuration). Съответно трябва и параметрите им да се настроят правилно, за да се получи желания резултат.

0
donstany avatar donstany 5 Точки

Здравей,

Аз ти благодаря за отговора.

Според теб това е верния подход:

в приложението да се напише в съответния entity клас:

@Entity

@SequenceGenerator(name="seq", initialValue=1, allocationSize=10000)
public class EntityWithSequenceId {
    // Use the sequence that is defined above:
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="seq")
    @Id long id;
}

 

и

в базата де се изпълни това

CREATE SEQUENCE seq
      INCREMENT BY 1
      START WITH 1
      NOMAXVALUE
      NOCYCLE
      CACHE 10;

0
deyan.zhekov avatar deyan.zhekov 159 Точки

Здравей,

и двете стратегии би следвало да работят, но... какво ще се случи ако имаш 2 application server-a сочещи към една база от данни?

Иначе браво за research-a. Това е много важно умение за всеки developer.

1
donstany avatar donstany 5 Точки

Благодаря за отговора!

Точно това се питам и аз ? :) ... "какво ще се случи, ако имаш 2 application server-a сочещи към една база от данни"?

Какъв е начина да се направи някакъв междинен "буфер"  /some pattern , or proxi,  or whatever ... /, който да управлява процеса по правилното  вземане на индекси от поредицата направена в базата ?

Според мен "буфера" (това си е мое рабиране за междинното звено) трабва по някакъв начин да е "пред" базата , за да обработвата правилно запитванията и отговорите от 2-та aplication-a с цел да се дават коректни индекси от поредицата или тригера ..?

Малко ми прилича постановката на front controller при който на входа постъпват две заявки от 2 app-a, може и едновременно да постъпват .

Освен това наподобява и на многонишковото програмиране.Колкото и да се едновременни 2-те заявки от двата app-a към базата все пак единия е преди другия.

Има един колега преподавател от СофтУни, който казваше така цитирам по спомен : "Това е като да имаш една тоалетна и двама човека искат да влязат едновременно, но при равни други условия все пак единия е по-бърз и другия трябва да изчака , т.е. влезлия си свършва работата, а втория го изчаква ..." според мен трябва да има един "буфер" коридор с портиер , който да казва "ти беше пръв, другия да изчака в коридора", като се освободи ресурса (WC) портиера казва  на втория бързак "хайде сега свърши твоята работа".  

Като същевременно тук задачата става много интересна, като трябва да се предвиди и backlog, т.е всички да се чакат, а WC да е свободно, може би портиера е заспал и той "душа" носи :) /трябва да се "ресетне", събуди .../.

Има два случая, които трябва да се разграничат:

- ако не "пипат", т.е. четат и/или пишат на едно и също място в базата всичко е ОК! (попаднали сме на WC с много кабинки като някои от тях са свободни);

- ако обаче имат някъде intersect-on (искат двама човека да влязат в една кабинка), втория app(чоек)  трябва да изчака да се извърши транзакцията на първия взел ресура, като веднага го заключва(заключва вратата след себе си и казва на портира да не пуска други, тук ако дойде трети портиера го спира и му казва: "чакай малко да излезе клиента, но преди теб има друг ти си след него...". През това време втория request от 2-рия чака първия и да приключи транзакцията, като този сигнал трябва да го получи като флаг от посредника "буфера";

Извинявам се образното описание, но много ми допадна и го запомних по лесно!

Ще се радвам, ако ми упътиш на къде да се насоча ...

 

 

 

 

0
08/04/2016 14:52:32
deyan.zhekov avatar deyan.zhekov 159 Точки

Здравей,

казусът най-лесно се решава с помощта на trigger в базата данни. В частния случай и твоите решения за приемливи.

Не отделяйте прекалено много време точно на това. Първо да работят функционалностите и после можете да мислите за "гъзарийките".

0
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.