sql >> Database teknologi >  >> RDS >> Mysql

Hvordan opretter man en generisk enhedsmodelklasse, der understøtter generisk id inklusive autogenererede id'er?

Prøvede ikke dette, men ifølge Hibernates api skulle dette ikke være kompliceret ved at skabe tilpasset implementering af IdentityGenerator .

Det er genereringsmetode-gets og objekt, som du genererer værdien for, så du kan kontrollere typen af ​​id-feltet og returnere passende værdi for din primære nøgle.

public class DynamicGenerator  implements IdentityGenerator

        public Serializable generate(SessionImplementor session, Object object)
                throws HibernateException {

             if (shouldUseAutoincrementStartegy(object)) { // basing on object detect if this should be autoincrement or not, for example inspect the type of id field by using reflection - if the type is Integer use IdentityGenerator, otherwise another generator 
                 return new IdentityGenerator().generate(seession, object)
             } else { // else if (shouldUseTextKey)

                 String textKey = generateKey(session, object); // generate key for your object

                 // you can of course connect to database here and execute statements if you need:
                 // Connection connection = session.connection();
                 //  PreparedStatement ps = connection.prepareStatement("SELECT nextkey from text_keys_table");
                 // (...)

                 return textKey;

            }

        }
    }

Når du har dette, skal du blot bruge det som din generationsstrategi:

@MappedSuperclass
public abstract class BaseEntity<T> implements Serializable {
    @Id
    @GenericGenerator(name="seq_id", strategy="my.package.DynamicGenerator")
    protected T id;
}

Til Hibernate 4 bør du implementere IdentifierGenerator grænseflade.

Som ovenstående er accepteret for Hibernate, burde det stadig være muligt at oprette det på en mere generisk måde for enhver "jpa-kompatibel" udbyder. Ifølge JPA api i GeneratedValue annotation kan du give din brugerdefinerede generator. Det betyder, at du kan angive navnet på din brugerdefinerede generator, og du bør implementere denne generator for hver jpa-udbyder.

Dette ville betyde, at du skal annotere BaseEntity med følgende annotation

@MappedSuperclass
public abstract class BaseEntity<T> implements Serializable {
    @Id
    @GeneratedValue(generator="my-custom-generator")
    protected T id;
}

Nu skal du registrere brugerdefineret generator med navnet "my-custom-generator" for hver jpa-udbyder, du gerne vil bruge.

For Hibernate gøres dette surt af @GenericGenerator-annotation som vist før (tilføje @GenericGenerator(name="my-custom-generator", strategy="my.package.DynamicGenerator" til BaseEntity klasse på enten id felt eller BaseEntity klasseniveau bør være tilstrækkeligt).

I EclipseLink ser jeg, at du kan gøre dette via GeneratedValue annotering og registrering af den via SessionCustomizer:

            properties.put(PersistenceUnitProperties.SESSION_CUSTOMIZER,
                    "my.custom.CustomIdGenerator");

public class CustomIdGenerator extends Sequence implements SessionCustomizer {


    @Override
    public Object getGeneratedValue(Accessor accessor,
            AbstractSession writeSession, String seqName) {
        return  "Id"; // generate the id
    }

    @Override
    public Vector getGeneratedVector(Accessor accessor,
            AbstractSession writeSession, String seqName, int size) {
        return null;
    }

    @Override
    protected void onConnect() {
    }

    @Override
    protected void onDisconnect() {
    }

    @Override
    public boolean shouldAcquireValueAfterInsert() {
        return false;
    }

    @Override
    public boolean shouldOverrideExistingValue(String seqName,
            Object existingValue) {
        return ((String) existingValue).isEmpty();
    }

    @Override
    public boolean shouldUseTransaction() {
        return false;
    }

    @Override
    public boolean shouldUsePreallocation() {
        return false;
    }

    public void customize(Session session) throws Exception {
        CustomIdGenerator sequence = new CustomIdGenerator ("my-custom-generator");

        session.getLogin().addSequence(sequence);
    }

}    

Hver udbyder skal give en måde at registrere id-generator på, så du bliver nødt til at implementere og registrere brugerdefinerede genereringsstrategier for hver af udbyderne, hvis du vil understøtte dem alle.



  1. ScaleGrid placeret blandt de 100 bedste cloud-udbydere

  2. sqlite række-id'er matcher ikke listevisning - ANDROID

  3. sql join to tabel

  4. mysqldump med utf8 kan ikke eksportere den rigtige emojis-streng