Oracle
 sql >> база данни >  >> RDS >> Oracle

Автоматично генериране на ключове в хибернация с MySQL и Oracle

Дори ако сте използвали GenerationType.AUTO без параметър, специфичен за SEQUENCE, няма да можете да запазите присвоените идентификатори.

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

  1. Един от начините е да преминете към присвоените идентификатори. Можете да използвате UUID идентификатори, които работят както за MySQL, така и за Oracle и можете също да зададете стойностите ръчно.

  2. Друг начин е да използвате персонализиран генератор на таблици.

Първо дефинирате идентифицируем интерфейс:

    public interface Identifiable<T extends Serializable> {
        T getId();
    }

След това разширявате генератора на таблици:

    public class AssignedTableGenerator extends TableGenerator {

        @Override
        public Serializable generate(SessionImplementor session, Object obj) {
            if(obj instanceof Identifiable) {
                Identifiable identifiable = (Identifiable) obj;
                Serializable id = identifiable.getId();
                if(id != null) {
                    return id;
                }
            }
            return super.generate(session, obj);
        }
    }

Този генератор е в състояние да смесва присвоени идентификатори със синтетично генерирани такива:

    doInTransaction(session -> {
        for (int i = 0; i < 5; i++) {
            session.persist(new AssignTableSequenceIdentifier());
        }
        AssignTableSequenceIdentifier tableSequenceIdentifier = new AssignTableSequenceIdentifier();
        tableSequenceIdentifier.id = -1L;
        session.merge(tableSequenceIdentifier);
        session.flush();
    });

генериране на следните изрази:

    select tbl.next_val from sequence_table tbl where tbl.sequence_name=default for update
    insert into sequence_table (sequence_name, next_val)  values (default,1)
    update sequence_table set next_val=2  where next_val=1 and sequence_name=default
    select tbl.next_val from sequence_table tbl where tbl.sequence_name=default for update
    update sequence_table set next_val=3  where next_val=2 and sequence_name=default
    select tbl.next_val from sequence_table tbl where tbl.sequence_name=default for update
    update sequence_table set next_val=4  where next_val=3 and sequence_name=default
    select tbl.next_val from sequence_table tbl where tbl.sequence_name=default for update
    update sequence_table set next_val=5  where next_val=4 and sequence_name=default
    select tbl.next_val from sequence_table tbl where tbl.sequence_name=default for update
    update sequence_table set next_val=6  where next_val=5 and sequence_name=default
    select identityvs0_.id as id1_0_0_ from assigneTableIdentifier identityvs0_ where identityvs0_.id=-1
    insert into assigneTableIdentifier (id) values (1, 2)
    insert into assigneTableIdentifier (id) values (2, 4)
    insert into assigneTableIdentifier (id) values (5, -1)

За Oracle можете да комбинирате SEQUENCE и назначените генератори. Накратко, имайки предвид следния генератор:

public class AssignedSequenceStyleGenerator 
    extends SequenceStyleGenerator {
 
    @Override
    public Serializable generate(SessionImplementor session, 
        Object obj) {
        if(obj instanceof Identifiable) {
            Identifiable identifiable = (Identifiable) obj;
            Serializable id = identifiable.getId();
            if(id != null) {
                return id;
            }
        }
        return super.generate(session, obj);
    }
}

Можете да го съпоставите с вашите обекти, както следва:

@Id
@GenericGenerator(
    name = "assigned-sequence",
    strategy = "com.vladmihalcea.book.hpjp.hibernate.identifier.AssignedSequenceStyleGenerator",
    parameters = @org.hibernate.annotations.Parameter(
        name = "sequence_name", 
        value = "post_sequence"
    )
)
@GeneratedValue(
    generator = "assigned-sequence", 
    strategy = GenerationType.SEQUENCE
)
private Long id;

Целият код е достъпен в GitHub и работи като чар.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. ORA-01461:може да обвърже LONG стойност само за вмъкване в LONG колона - Възниква при запитване

  2. как да обединя повече от две колони в plsql developer?

  3. Какви ситуации причиняват пакетите на Oracle да станат невалидни?

  4. ORA-01438:стойност, по-голяма от определената прецизност, позволена за тази колона при вмъкване на 3

  5. Как да промените формата на датата във вашата сесия на Oracle