Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Jak utworzyć ogólną klasę modelu jednostki, która obsługuje identyfikator ogólny, w tym identyfikatory generowane automatycznie?

Nie próbowałem tego, ale zgodnie z api Hibernate nie powinno to być skomplikowane przez tworzenie niestandardowej implementacji IdentityGenerator .

Jest to metoda generate i obiekt, dla którego generujesz wartość, dzięki czemu możesz sprawdzić typ pola id i zwrócić odpowiednią wartość dla swojego klucza podstawowego.

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;

            }

        }
    }

Mając to, po prostu użyj go jako strategii generowania:

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

W przypadku Hibernate 4 należy zaimplementować IdentifierGenerator interfejs.

Jak powyżej jest akceptowane dla Hibernate, nadal powinno być możliwe stworzenie go w bardziej ogólny sposób dla dowolnego dostawcy "zgodnego z jpa". Według JPA api w GeneratedValue adnotację, którą możesz podać w swoim niestandardowym generatorze. Oznacza to, że możesz podać nazwę swojego niestandardowego generatora i powinieneś zaimplementować ten generator dla każdego dostawcy jpa.

Oznaczałoby to, że musisz dodać do BaseEntity następującą adnotację

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

Teraz musisz zarejestrować niestandardowy generator o nazwie "my-custom-generator" dla każdego dostawcy jpa, którego chcesz użyć.

W przypadku Hibernate jest to z pewnością wykonywane przez adnotację @GenericGenerator, jak pokazano wcześniej (dodając @GenericGenerator(name="my-custom-generator", strategy="my.package.DynamicGenerator" do BaseEntity klasa na id pole lub BaseEntity poziom klasy powinien być wystarczający).

W EclipseLink widzę, że możesz to zrobić za pomocą GeneratedValue adnotację i rejestrację za pomocą 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);
    }

}    

Każdy dostawca musi umożliwić zarejestrowanie generatora identyfikatorów, więc jeśli chcesz obsługiwać ich wszystkich, musisz wdrożyć i zarejestrować niestandardową strategię generowania dla każdego dostawcy.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jaka jest najlepsza metoda używania / przechowywania kluczy szyfrowania w MySQL?

  2. SQLite w Androidzie:oczekiwano kluczy obcych i <ograniczenie tabeli>

  3. Połączenie MySQL nie działa

  4. MySQLi - deklarowanie zmiennej po bind_param?

  5. SQL:Wybierz klucze, które nie istnieją w jednej tabeli