sql >> Databasteknik >  >> RDS >> Oracle

Lägg automatisk nyckelgenerering i viloläge med MySQL och Oracle

Även om du använde GenerationType.AUTO utan någon SEQUENCE-specifik parameter skulle du inte kunna spara tilldelade identifierare.

Det finns några lösningar om du är villig att göra några kompromisser:

  1. Ett sätt skulle vara att byta till de tilldelade identifierarna. Du kan använda UUID-identifierare, som fungerar för både MySQL och Oracle och du kan även tilldela värdena manuellt.

  2. Ett annat sätt är att använda en anpassad tabellgenerator.

Först definierar du ett identifierbart gränssnitt:

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

Sedan utökar du tabellgeneratorn:

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

Denna generator kan blanda tilldelade identifierare med syntetiskt genererade:

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

genererar följande påståenden:

    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)

För Oracle kan du kombinera SEQUENCE och de tilldelade generatorerna. Kort sagt, med tanke på följande 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);
    }
}

Du kan mappa den till dina enheter enligt följande:

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

All kod är tillgänglig på GitHub och fungerar som en charm.



  1. SQLite har

  2. Postgresql Trunkeringshastighet

  3. Meddelar att SQL Compliance Manager 5.9 är allmänt tillgänglig

  4. Kan du dra nytta av en anpassad databasapplikation?