Nakolik vidim do toho zdrojaku tak je to presne to, co potrebuju. Jenom si nejsem jist, jak se to zachova u primitivnich typu, ale to vyzkousim.
Diky! 2010/10/18 Jaroslav Hurdes <[email protected]>: > Zdravim vsechny. Ja jsem ve svem projektu potreboval totez, a navic jsem > potreboval pri generovani id provest jeho upravu, abych mohl slucovat data z > vice databazi a vyresil jsem to svou implementaci generatoru ID. > Tento generator pozna zda je id nastaveno a pokud je ponecha jej, pokud neni > pouzije bud sekvenci (je li podporovana), nebo HILO generovani, neni li. > Nize zasilam ukazku. Jiste nebude pro vas problem toto upravit pro sve > pouziti. > > Jaroslav Hurdes > > import java.io.Serializable; > import java.util.Properties; > > import org.hibernate.HibernateException; > import org.hibernate.Interceptor; > import org.hibernate.MappingException; > import org.hibernate.dialect.Dialect; > import org.hibernate.engine.SessionImplementor; > import org.hibernate.id.Configurable; > import org.hibernate.id.IdentifierGenerationException; > import org.hibernate.id.IdentifierGenerator; > import org.hibernate.id.PersistentIdentifierGenerator; > import org.hibernate.id.SequenceGenerator; > import org.hibernate.id.TableHiLoGenerator; > import org.hibernate.persister.entity.EntityPersister; > import org.hibernate.type.Type; > > /** > * Trida implementujici generator identit pouzitelny > * v distribuovanem prostredi. > * > * @author Jaroslav Hurdes > */ > public class DistributedDbSequenceIdGenerator implements > PersistentIdentifierGenerator, Configurable { > public static final String STRATEGY_NAME = > "cz.hurdes.common.business.data.DistributedDbSequenceIdGenerator"; > > protected Type identifierType; > protected IdentifierGenerator idGenerator; > protected boolean sequenceGenerator; > > /** > * Konfigurace generatoru identit > */ > public void configure(Type type, Properties parameters, Dialect dialect) > throws MappingException { > > identifierType = type; > idGenerator = null; > > sequenceGenerator = dialect.supportsSequences(); > if(sequenceGenerator) { > idGenerator = new SequenceGenerator(); > } else { > idGenerator = new TableHiLoGenerator(); > } > > if(idGenerator instanceof Configurable) { > ((Configurable)idGenerator).configure(type, parameters, dialect); > } > } > > /** > * Generovani klice > */ > public Serializable generate(SessionImplementor sessionImpl, Object obj) > throws HibernateException { > > Serializable assignedId = getAssignedId(sessionImpl, obj); > if(assignedId != null) { > // Pokud je klic zadany, potom jej nechame tak jak je > return assignedId; > } else { > // Vygenerujeme novy klic > Serializable result = idGenerator.generate(sessionImpl, obj); > result = addDbIdentificator(result); > return result; > } > > > } > > /** > * Metoda otestuje, zda je zadan identifikator. > * @param sessionImpl > * @param obj > * @return > */ > private Serializable getAssignedId(SessionImplementor sessionImpl, Object > obj) { > Interceptor interceptor = sessionImpl.getInterceptor(); > String entityName = interceptor.getEntityName(obj); > EntityPersister persister = > sessionImpl.getEntityPersister(entityName, obj); > Serializable id = persister.getIdentifier(obj, > sessionImpl.getEntityMode()); > > return id; > } > > /** > * Modifikace vygenerovaneho klice pro pouziti v distribuovanem prostredi > * podle prislusne databaze > * > * @param key puvodni klic > * @return modifikovany klic > */ > private Serializable addDbIdentificator(Serializable key) { > if(DistributedDbParameters.getParameters().isBaseSetting()) { > return key; > } > > Class idClass = identifierType.getReturnedClass(); > > int multiplier = > DistributedDbParameters.getParameters().getMultiplier(); > int databaseId = > DistributedDbParameters.getParameters().getDatabaseId(); > > if(idClass == Long.class) { > key = (Long)key * multiplier + databaseId; > } else if(idClass == Integer.class) { > key = (Integer)key * multiplier + databaseId; > } else if(idClass == Short.class) { > key = (Short)key * multiplier + databaseId; > } else if(idClass == Short.class) { > key = ((String)key) + databaseId; > } else { > throw new IdentifierGenerationException("This id generator > generates long, " + > "integer, short or > string"); > } > > return key; > } > > public Object generatorKey() { > if(sequenceGenerator) { > return ((SequenceGenerator)idGenerator).generatorKey(); > } else { > return ((TableHiLoGenerator)idGenerator).generatorKey(); > } > } > > public String[] sqlCreateStrings(Dialect dialect) throws > HibernateException { > if(sequenceGenerator) { > return > ((SequenceGenerator)idGenerator).sqlCreateStrings(dialect); > } else { > return > ((TableHiLoGenerator)idGenerator).sqlCreateStrings(dialect); > } > } > > public String[] sqlDropStrings(Dialect dialect) throws HibernateException > { > if(sequenceGenerator) { > return ((SequenceGenerator)idGenerator).sqlDropStrings(dialect); > } else { > return ((TableHiLoGenerator)idGenerator).sqlDropStrings(dialect); > } > } > } > > Dne 18.10.2010 19:04, Oto Buchta napsal(a): >> >> Dne 18. října 2010 16:07 "Zdeněk Troníček"<[email protected]> >> napsal(a): >>> >>> Vidim dve cesty: >>> >>> 1) SQL: pomoci ALTER TABLE vypnout autoincrement, pokud je zapnuty, pak >>> vlozit data pomoci INSERT a autoincrement zase zapnout (zkousel jsem to v >>> MySQL a tam to funguje) >> >> Autoincrement nemám - používám seqenci. SQL jsem se ale právě chtěl >> vyhnout. >> >>> 2) Java: pomoci ALTER TABLE vypnout autoincrement, pokud je zapnuty; >>> zakomentovat anotaci @GeneratedValue a vlozit entity pres JPA; po vlozeni >>> obnovit anotaci @GeneratedValue a zapnout autoincrement >> >> Jak jsem psal, anotace použít nemohu... >> >>> Oto Buchta napsal(a): >>>> >>>> Dne 18. října 2010 10:54 "Zdeněk Troníček"<[email protected]> >>>> napsal(a): >>>>> >>>>> Takhle to funguje pro strategy s hodnotou GenerationType.AUTO. Tj. >>>>> pokud >>>>> id prideluje framework (Hibernate, EclipseLink,...), lze mu id >>>>> nadiktovat. >>>> >>>> Aha, dík za tip. Problém je v tom, že mi hodnota "auto" není >>>> definována pro >>>> http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd >>>> - org.hibernate.MappingException: could not interpret id generator >>>> strategy: auto >>>> >>>> No a protože mám Hibernate jako JBossí MBeanovou servisu, nemůžu použít >>>> anotaci. >>>> Je toto opravdu jediná možná cesta? >>>> >>>>> Pak je jeste nutne upravit hodnoty v tabulce SEQUENCE, protoze jinak >>>>> mohou >>>>> nasledujici em.persist(...) skoncit chybou "duplicitni hodnota >>>>> primarniho >>>>> klice". >>>>> Pokud ovsem id prideluje databaze (GenerationType.IDENTITY nebo >>>>> GenerationType.SEQUENCE), tak toto fungovat nebude, protoze sloupec id >>>>> muze byt v databazi deklarovan jako autoincrement a pak si pridelovani >>>>> hodnot ridi sama databaze. >>>>> >>>>> Z. >>>>> -- >>>>> Zdenek Tronicek >>>>> FIT CTU in Prague >>>>> >>>>> >>>>> Ondra Medek napsal(a): >>>>>> >>>>>> Ja mam JPA nad Hibernate, a kdyz u entity nastavim setId(...) a pak >>>>>> em.merge(entity), tak se mi ulozi s tim id, co jsem nastavil. Klice se >>>>>> generuji jen pro nove entity. Funguje pro HSQLB a Oracle. >>>>>> >>>>>> 2010/10/18 Oto Buchta<[email protected]>: >>>>>>> >>>>>>> Chci při instalaci nacpat do DB iniciální data a potřebuji, aby >>>>>>> některé záznamy typů s generovanými primárním klíčem měly >>>>>>> předdefinované hodnoty. Nemůžu ale nikde vygůglit jak na to. >>>>>>> Máte někdo nějakou ideu? >>>>>>> Dík. >>>>>>> -- >>>>>>> Oto 'tapik' Buchta, [email protected], http://tapikuv.blogspot.com >>>>>>> >>>>>> >>>>>> >>>>>> -- >>>>>> Ondra Medek >>>>>> >>>>> >>>> >>>> >>>> -- >>>> Oto 'tapik' Buchta, [email protected], http://tapikuv.blogspot.com >>>> >>> >> >> > > -- Oto 'tapik' Buchta, [email protected], http://tapikuv.blogspot.com
