Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Automatyczne generowanie kluczy hibernacji za pomocą MySQL i Oracle

Nawet jeśli użyłeś GenerationType.AUTO bez określonego parametru SEKWENCJI nie byłoby możliwe zapisanie przypisanych identyfikatorów.

Istnieje kilka obejść, jeśli chcesz pójść na pewne kompromisy:

  1. Jednym ze sposobów byłoby przełączenie się na przypisane identyfikatory. Możesz użyć identyfikatorów UUID, które działają zarówno dla MySQL, jak i Oracle, a także możesz przypisać wartości ręcznie.

  2. Innym sposobem jest użycie niestandardowego generatora tabel.

Najpierw zdefiniuj identyfikowalny interfejs:

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

Następnie rozszerzasz generator tabel:

    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);
        }
    }

Ten generator może mieszać przypisane identyfikatory z wygenerowanymi syntetycznie:

    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();
    });

generowanie następujących stwierdzeń:

    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)

W przypadku Oracle możesz połączyć SEQUENCE i przypisane generatory. W skrócie, biorąc pod uwagę następujący generator:

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);
    }
}

Możesz go zmapować do swoich jednostek w następujący sposób:

@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;

Cały kod jest dostępny na GitHub i działa jak czar.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. EM12c Baza danych czasu spędzonego na oczekiwaniu na alerty

  2. jak używać dbms_scheduler do uruchamiania zadania co 30 minut

  3. Jak uniknąć błędów mutacji tabel

  4. Czy w ORACLE istnieje sposób na połączenie wielu wierszy w jeden, przy użyciu dwóch tabel, w których końcowe wartości są oddzielone przecinkami?

  5. Jak usunąć część sznurka w Oracle?