Hazırda Bekleme JPA Dizisi (Kimliksiz)


138

Tanımlayıcı olmayan / bileşik tanımlayıcının bir parçası olmayan bazı sütunlar için bir DB sırası kullanmak mümkün müdür ?

Hazırda bekleme jpa sağlayıcısı olarak kullanıyorum ve tanımlayıcı bir parçası olmasa da (bir sıra kullanarak) oluşturulan değerler bazı sütunları olan bir tablo var.

Ne istediğim sıra için sütun birincil anahtar (parçası değil ) bir varlık için yeni bir değer oluşturmak için bir sıra kullanmaktır :

@Entity
@Table(name = "MyTable")
public class MyEntity {

    //...
    @Id //... etc
    public Long getId() {
        return id;
    }

   //note NO @Id here! but this doesn't work...
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "myGen")
    @SequenceGenerator(name = "myGen", sequenceName = "MY_SEQUENCE")
    @Column(name = "SEQ_VAL", unique = false, nullable = false, insertable = true, updatable = true)
    public Long getMySequencedValue(){
      return myVal;
    }

}

Sonra bunu yaptığımda:

em.persist(new MyEntity());

kimlik oluşturulur, ancak mySequenceValözellik JPA sağlayıcım tarafından da oluşturulur.

Sadece işleri netleştirmek için: HibernatemySequencedValue özelliği için değer üretmek istiyorum . Hazırda Beklet'in veritabanı tarafından oluşturulan değerleri işleyebileceğini biliyorum, ancak mülküm için değer oluşturmak üzere bir tetikleyici veya Hazırda Beklet dışında başka bir şey kullanmak istemiyorum. Hazırda Bekletme birincil anahtarlar için değer üretebiliyorsa, neden basit bir özellik için üretilemiyor?

Yanıtlar:


77

Bu sorunun cevabını arıyorum, bu bağlantıya tökezledim

Hibernate / JPA, kimlik dışı mülkleriniz için otomatik olarak bir değer oluşturamıyor gibi görünüyor. @GeneratedValueİle ek açıklama sadece birlikte kullanılır @Idotomatik numaralarını oluşturun.

@GeneratedValueEk açıklama sadece veritabanı bu değeri kendisi oluşturmakta olduğunu Hibernate söyler.

Bu forumda önerilen çözüm (veya geçici çözüm), oluşturulan bir kimliğe sahip ayrı bir varlık oluşturmaktır.

@Entity
public class GeneralSequenceNumber {
  @İD
  @GeneratedValue (...)
  özel Uzun sayı;
}

@Entity 
herkese açık sınıf MyEntity {
  @Id ..
  özel Uzun kimlik;

  @Bire bir(...)
  özel GeneralSequnceNumber myVal;
}

@GeneratedValue adlı java doc'den: "GeneratedValue ek açıklaması, bir varlığın birincil anahtar özelliğine veya alanına veya

11
@Column (columnDefinition = "seri") mükemmel ama sadece PostgreSQL için çalıştığını buldum. Benim için bu mükemmel bir çözümdü, çünkü ikinci varlık "çirkin" bir seçenek
Sergey Vedernikov

@SergeyVedernikov son derece yardımcı oldu. Bunu ayrı bir cevap olarak yayınlamak ister misiniz? Sorunumu çok basit ve etkili bir şekilde çözdü.
Matt Ball

@MattBall Bunu ayrı bir cevap olarak gönderdim :) stackoverflow.com/a/10647933/620858
Sergey Vedernikov

1
@GeneratedValueKimliği olmayan alanlara izin vermek için bir teklif açtım . 2.2 java.net/jira/browse/JPA_SPEC-113
Petar Tahchiev

44

@Column(columnDefinition="serial")Mükemmel çalıştığını ancak sadece PostgreSQL için çalıştığını gördüm . Benim için bu mükemmel bir çözümdü, çünkü ikinci varlık "çirkin" bir seçenek.


Merhaba, bununla ilgili bir açıklamaya ihtiyacım var. Bana biraz daha anlatır mısınız?
Emaborsa

2
@Emaborsa columnDefinition=Bit temel olarak Hiberate'ye sütun tanımı oluşturmaya çalışmamasını ve bunun yerine verdiğiniz metni kullanmamasını söyler. Esasen, sütun için DDL'niz tam anlamıyla name + columnDefinition olacaktır. Bu durumda (PostgreSQL), mycolumn serialbir tabloda geçerli bir sütundur.
Patrick

7
MySQL için eşdeğer@Column(columnDefinition = "integer auto_increment")
Richard Kennard

2
Bu otomatik olarak değer yaratıyor mu? Böyle bir alan tanımı ile bir varlık ısrar denedim ama bir değer üretmedi. <column> sütununda boş değer attı, boş olmayan kısıtlamayı ihlal ediyor
KyelJmD

7
Kullandığım @Column(insertable = false, updatable = false, columnDefinition="serial")boş değerler eklemeye çalışıyor ya alanını güncellenmesini hazırda önlemek için. Daha sonra derhal kullanmanız gerekiyorsa, bir eklemeden sonra oluşturulan kimliği almak için db'yi yeniden sorgulamanız gerekir.
Robert Di Paolo

20

Bunun çok eski bir soru olduğunu biliyorum, ama önce sonuçlar üzerinde gösterildi ve jpa bu sorudan bu yana çok değişti.

Şimdi yapmanın doğru yolu @Generatedek açıklamadır. Sekansı tanımlayabilir, sütundaki varsayılanı bu sekansa ayarlayabilir ve ardından sütunu şu şekilde eşleyebilirsiniz:

@Generated(GenerationTime.INSERT)
@Column(name = "column_name", insertable = false)

1
Bu hala değerin veritabanı tarafından oluşturulmasını gerektirir ve bu da soruyu gerçekten yanıtlamaz. 12c'den önceki Oracle veritabanlarında, değeri oluşturmak için yine de bir veritabanı tetikleyicisi yazmanız gerekir.
Bernie

9
ayrıca, bu bir Hazırda Bekletme notudur, JPA değil.
caarlos0

14

Hazırda Bekletme kesinlikle bunu desteklemektedir. Dokümanlardan:

"Oluşturulan özellikler, değerleri veritabanı tarafından oluşturulan özelliklerdir. Genelde, veritabanının değer ürettiği özellikleri içeren nesneleri yenilemek için gereken Hazırda Bekletme uygulamaları. Ancak, özellikleri oluşturulduğu gibi işaretlemek, uygulamanın bu sorumluluğu Hazırda Bekletme yetkisine vermesine izin verir. Esas olarak, Hazırda Bekletme modu, oluşturulan özellikleri tanımlayan bir varlık için bir SQL INSERT veya UPDATE yayınladığında, oluşturulan değerleri almak için hemen bir seçim yapar. "

Yalnızca ekte oluşturulan mülkler için mülk eşlemeniz (.hbm.xml) şöyle görünür:

<property name="foo" generated="insert"/>

Ekleme ve güncelleme üzerine oluşturulan özellikler için özellik eşlemeniz (.hbm.xml) şöyle görünür:

<property name="foo" generated="always"/>

Ne yazık ki, JPA bilmiyorum, bu yüzden bu özelliğin JPA ile maruz kaldığını bilmiyorum (muhtemelen şüpheleniyorum)

Alternatif olarak, özelliği ekler ve güncellemelerden hariç tutabilmeniz ve daha sonra "el ile" call.refresh (obj); oluşturulan değeri veritabanından yüklemek için ekledikten / güncelledikten sonra.

Özelliğin ekleme ve güncelleme ifadelerinde kullanılmasını şu şekilde hariç tutabilirsiniz:

<property name="foo" update="false" insert="false"/>

Yine, JPA'nın bu Hazırda Bekletme özelliklerini gösterip göstermediğini bilmiyorum, ancak Hazırda Beklet bunları destekliyor.


1
@Generated ek açıklama yukarıdaki XML yapılandırmasına karşılık gelir. Daha fazla bilgi için hazırda bekletme belgelerinin bu bölümüne bakın.
Eric

8

Bir takip olarak nasıl çalıştırabilirim:

@Override public Long getNextExternalId() {
    BigDecimal seq =
        (BigDecimal)((List)em.createNativeQuery("select col_msd_external_id_seq.nextval from dual").getResultList()).get(0);
    return seq.longValue();
}

Hazırda Bekletme 4.2.19 ve kehanetle bir değişken: SQLQuery sqlQuery = getSession().createSQLQuery("select NAMED_SEQ.nextval seq from dual"); sqlQuery.addScalar("seq", LongType.INSTANCE); return (Long) sqlQuery.uniqueResult();
Aaron

6

@PrePersistEk açıklama kullanarak Hazırda Bekletme ile UUID (veya dizileri) oluşturulmasını düzelttim :

@PrePersist
public void initializeUUID() {
    if (uuid == null) {
        uuid = UUID.randomUUID().toString();
    }
}

5

Bu eski bir iş parçacığı olmasına rağmen benim çözüm paylaşmak ve umarım bu konuda bazı geribildirim almak istiyorum. Bu çözümü yalnızca bazı JUnit test çantasında yerel veritabanımla test ettiğim konusunda uyarıda bulunun. Yani bu şimdiye kadar üretken bir özellik değil.

Ben bu özelliği benim için hiçbir özellik ile Sequence adlı özel bir açıklama getirerek çözdü. Bu, artırılmış bir diziden bir değer atanması gereken alanlar için yalnızca bir işaretleyicidir.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Sequence
{
}

Bu ek açıklamayı kullanarak varlıklarımı işaretledim.

public class Area extends BaseEntity implements ClientAware, IssuerAware
{
    @Column(name = "areaNumber", updatable = false)
    @Sequence
    private Integer areaNumber;
....
}

Şeyler veritabanını bağımsız tutmak için dizi geçerli değeri ve artış boyutunu tutan SequenceNumber adlı bir varlık tanıttı. ClassName benzersiz anahtar olarak seçtim, böylece her varlık sınıfı kendi dizisini alacak.

@Entity
@Table(name = "SequenceNumber", uniqueConstraints = { @UniqueConstraint(columnNames = { "className" }) })
public class SequenceNumber
{
    @Id
    @Column(name = "className", updatable = false)
    private String className;

    @Column(name = "nextValue")
    private Integer nextValue = 1;

    @Column(name = "incrementValue")
    private Integer incrementValue = 10;

    ... some getters and setters ....
}

Son adım ve en zoru, sıra numarası atamasını işleyen bir PreInsertListener'dır. Fasulye kabı olarak yay kullandığımı unutmayın.

@Component
public class SequenceListener implements PreInsertEventListener
{
    private static final long serialVersionUID = 7946581162328559098L;
    private final static Logger log = Logger.getLogger(SequenceListener.class);

    @Autowired
    private SessionFactoryImplementor sessionFactoryImpl;

    private final Map<String, CacheEntry> cache = new HashMap<>();

    @PostConstruct
    public void selfRegister()
    {
        // As you might expect, an EventListenerRegistry is the place with which event listeners are registered
        // It is a service so we look it up using the service registry
        final EventListenerRegistry eventListenerRegistry = sessionFactoryImpl.getServiceRegistry().getService(EventListenerRegistry.class);

        // add the listener to the end of the listener chain
        eventListenerRegistry.appendListeners(EventType.PRE_INSERT, this);
    }

    @Override
    public boolean onPreInsert(PreInsertEvent p_event)
    {
        updateSequenceValue(p_event.getEntity(), p_event.getState(), p_event.getPersister().getPropertyNames());

        return false;
    }

    private void updateSequenceValue(Object p_entity, Object[] p_state, String[] p_propertyNames)
    {
        try
        {
            List<Field> fields = ReflectUtil.getFields(p_entity.getClass(), null, Sequence.class);

            if (!fields.isEmpty())
            {
                if (log.isDebugEnabled())
                {
                    log.debug("Intercepted custom sequence entity.");
                }

                for (Field field : fields)
                {
                    Integer value = getSequenceNumber(p_entity.getClass().getName());

                    field.setAccessible(true);
                    field.set(p_entity, value);
                    setPropertyState(p_state, p_propertyNames, field.getName(), value);

                    if (log.isDebugEnabled())
                    {
                        LogMF.debug(log, "Set {0} property to {1}.", new Object[] { field, value });
                    }
                }
            }
        }
        catch (Exception e)
        {
            log.error("Failed to set sequence property.", e);
        }
    }

    private Integer getSequenceNumber(String p_className)
    {
        synchronized (cache)
        {
            CacheEntry current = cache.get(p_className);

            // not in cache yet => load from database
            if ((current == null) || current.isEmpty())
            {
                boolean insert = false;
                StatelessSession session = sessionFactoryImpl.openStatelessSession();
                session.beginTransaction();

                SequenceNumber sequenceNumber = (SequenceNumber) session.get(SequenceNumber.class, p_className);

                // not in database yet => create new sequence
                if (sequenceNumber == null)
                {
                    sequenceNumber = new SequenceNumber();
                    sequenceNumber.setClassName(p_className);
                    insert = true;
                }

                current = new CacheEntry(sequenceNumber.getNextValue() + sequenceNumber.getIncrementValue(), sequenceNumber.getNextValue());
                cache.put(p_className, current);
                sequenceNumber.setNextValue(sequenceNumber.getNextValue() + sequenceNumber.getIncrementValue());

                if (insert)
                {
                    session.insert(sequenceNumber);
                }
                else
                {
                    session.update(sequenceNumber);
                }
                session.getTransaction().commit();
                session.close();
            }

            return current.next();
        }
    }

    private void setPropertyState(Object[] propertyStates, String[] propertyNames, String propertyName, Object propertyState)
    {
        for (int i = 0; i < propertyNames.length; i++)
        {
            if (propertyName.equals(propertyNames[i]))
            {
                propertyStates[i] = propertyState;
                return;
            }
        }
    }

    private static class CacheEntry
    {
        private int current;
        private final int limit;

        public CacheEntry(final int p_limit, final int p_current)
        {
            current = p_current;
            limit = p_limit;
        }

        public Integer next()
        {
            return current++;
        }

        public boolean isEmpty()
        {
            return current >= limit;
        }
    }
}

Yukarıdaki koddan da görebileceğiniz gibi, dinleyici varlık sınıfı başına bir SequenceNumber örneği kullandı ve SequenceNumber varlığının incrementValue tarafından tanımlanan birkaç sıra numarası ayırır. Sıra numaraları biterse, hedef sınıf için SequenceNumber varlığını yükler ve sonraki çağrılar için incrementValue değerlerini saklar. Bu şekilde bir dizi değeri gerektiğinde veritabanını sorgulamak gerekmez. Sonraki sıra numarası kümesini ayırmak için açılan StatelessSession'a dikkat edin. EntityPersister'da bir ConcurrentModificationException özelliğine yol açacağından, hedef varlığın devam etmekte olduğu oturumu kullanamazsınız.

Umarım bu birine yardımcı olur.


5

Postgresql kullanıyorsanız
Ve ben bahar önyükleme 1.5.6 kullanıyorum

@Column(columnDefinition = "serial")
@Generated(GenerationTime.INSERT)
private Integer orderID;

1
Ben zaten işaret ne ek olarak, yay çizme 2.1.6.RELEASE, Hazırda 5.3.10.Final kullanıyorum, benim için çok çalıştı, ben secuence oluşturmak zorunda kaldı seq_order, alan ve marka başvuru formunu nextval('seq_order'::regclass)
OJVM

3

Senin gibi aynı durumda koşuyorum ve temelde JPA ile id olmayan mülkler oluşturmak mümkün olup olmadığını da ciddi bir cevap bulamadım.

Benim çözüm, özelliği devam etmeden önce el ile ayarlamak için yerel bir JPA sorgusu ile sıra çağırmaktır.

Bu tatmin edici değil ama şu an için bir çözüm olarak çalışıyor.

Mario


2

Bu özel notu oturumda buldum 9.1.9 JPA belirtiminden GeneratedValue Ek Açıklaması: "[43] Taşınabilir uygulamalar GeneratedValue ek açıklamasını diğer kalıcı alanlarda veya özelliklerde kullanmamalıdır." Bu nedenle, en azından sadece JPA kullanarak birincil olmayan anahtar değerler için otomatik olarak değer üretmenin mümkün olmadığını varsayıyorum.


1

Görünüşe göre iş parçacığı eski, ben sadece benim çözüm eklemek istedim (İlkbaharda AspectJ - AOP kullanarak).

Çözüm, @InjectSequenceValueaşağıdaki gibi özel bir açıklama oluşturmaktır .

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface InjectSequenceValue {
    String sequencename();
}

Artık varlıktaki herhangi bir alana açıklama ekleyebilirsiniz, böylece temel alan (Uzun / Tamsayı) değeri, dizinin bir sonraki değeri kullanılarak çalışma zamanında enjekte edilir.

Buna açıklama ekleyin.

//serialNumber will be injected dynamically, with the next value of the serialnum_sequence.
 @InjectSequenceValue(sequencename = "serialnum_sequence") 
  Long serialNumber;

Şimdiye kadar, dizi değerini enjekte etmemiz gereken alanı işaretledik, bu yüzden dizi değerini işaretli alanlara nasıl enjekte edeceğimize bakacağız, bu AspectJ'de nokta kesimi oluşturarak yapılır.

Enjeksiyon, save/persistyöntem uygulanmadan hemen önce tetiklenecektir . Bu, aşağıdaki sınıfta yapılır.

@Aspect
@Configuration
public class AspectDefinition {

    @Autowired
    JdbcTemplate jdbcTemplate;


    //@Before("execution(* org.hibernate.session.save(..))") Use this for Hibernate.(also include session.save())
    @Before("execution(* org.springframework.data.repository.CrudRepository.save(..))") //This is for JPA.
    public void generateSequence(JoinPoint joinPoint){

        Object [] aragumentList=joinPoint.getArgs(); //Getting all arguments of the save
        for (Object arg :aragumentList ) {
            if (arg.getClass().isAnnotationPresent(Entity.class)){ // getting the Entity class

                Field[] fields = arg.getClass().getDeclaredFields();
                for (Field field : fields) {
                    if (field.isAnnotationPresent(InjectSequenceValue.class)) { //getting annotated fields

                        field.setAccessible(true); 
                        try {
                            if (field.get(arg) == null){ // Setting the next value
                                String sequenceName=field.getAnnotation(InjectSequenceValue.class).sequencename();
                                long nextval=getNextValue(sequenceName);
                                System.out.println("Next value :"+nextval); //TODO remove sout.
                                field.set(arg, nextval);
                            }

                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }

        }
    }

    /**
     * This method fetches the next value from sequence
     * @param sequence
     * @return
     */

    public long getNextValue(String sequence){
        long sequenceNextVal=0L;

        SqlRowSet sqlRowSet= jdbcTemplate.queryForRowSet("SELECT "+sequence+".NEXTVAL as value FROM DUAL");
        while (sqlRowSet.next()){
            sequenceNextVal=sqlRowSet.getLong("value");

        }
        return  sequenceNextVal;
    }
}

Şimdi herhangi bir Varlığa aşağıdaki gibi açıklama ekleyebilirsiniz.

@Entity
@Table(name = "T_USER")
public class UserEntity {

    @Id
    @SequenceGenerator(sequenceName = "userid_sequence",name = "this_seq")
    @GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "this_seq")
    Long id;
    String userName;
    String password;

    @InjectSequenceValue(sequencename = "serialnum_sequence") // this will be injected at the time of saving.
    Long serialNumber;

    String name;
}

0

"Mülkümün değerini oluşturmak için bir tetikleyici veya Hazırda Bekletme dışında başka bir şey kullanmak istemiyorum"

Bu durumda, gerekli değeri üreten bir UserType uygulaması oluşturmaya ve meta verileri mySequenceVal özelliğinin kalıcılığı için bu UserType'ı kullanacak şekilde yapılandırmaya ne dersiniz?


0

Bu, bir sekans kullanmakla aynı şey değildir. Bir sekans kullanırken hiçbir şey eklemez veya güncellemezsiniz. Bir sonraki sıra değerini alıyorsunuz. Hazırda bekletme modu desteklemiyor gibi görünüyor.


0

UNIQUEIDENTIFIER türüne sahip bir sütununuz varsa ve ekleme için varsayılan oluşturma gerekiyorsa, ancak sütun PK değilse

@Generated(GenerationTime.INSERT)
@Column(nullable = false , columnDefinition="UNIQUEIDENTIFIER")
private String uuidValue;

Db içinde olacak

CREATE TABLE operation.Table1
(
    Id         INT IDENTITY (1,1)               NOT NULL,
    UuidValue  UNIQUEIDENTIFIER DEFAULT NEWID() NOT NULL)

Bu durumda jeneratörü ihtiyacınız olan bir değer için tanımlamayacaksınız (sayesinde otomatik olarak olacaktır columnDefinition="UNIQUEIDENTIFIER"). Aynı diğer sütun türleri için deneyebilirsiniz


0

Bir Spring uygulamasında @PostConstruct ve JdbcTemplate kullanarak MySql veritabanlarında bunun için bir geçici çözüm buldum. Diğer veritabanları ile yapılabilir, ancak sunacağım kullanım durumu auto_increment kullandığından MySql ile olan deneyimime dayanmaktadır.

İlk olarak, @Column ek açıklamasının ColumnDefinition özelliğini kullanarak bir sütunu auto_increment olarak tanımlamayı denemiştim, ancak sütunun otomatik artımlı olması için bir anahtar olması gerekiyordu, ancak görünüşe göre sütun olarak tanımlanmayacaktı bir dizinin tanımlanmasından sonraya kadar bir kilitlenmeye neden olması.

Burada, auto_increment tanımı olmadan sütun oluşturma ve veritabanı oluşturulduktan sonra onu ekleme fikriyle geldim . Bu, uygulama fasulye başlatıldıktan hemen sonra JdbcTemplate'in güncelleme yöntemiyle birlikte bir yöntemin çağrılmasına neden olan @PostConstruct ek açıklaması kullanılarak mümkündür.

Kod aşağıdaki gibidir:

Varlığımda:

@Entity
@Table(name = "MyTable", indexes = { @Index(name = "my_index", columnList = "mySequencedValue") })
public class MyEntity {
    //...
    @Column(columnDefinition = "integer unsigned", nullable = false, updatable = false, insertable = false)
    private Long mySequencedValue;
    //...
}

PostConstructComponent sınıfında:

@Component
public class PostConstructComponent {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @PostConstruct
    public void makeMyEntityMySequencedValueAutoIncremental() {
        jdbcTemplate.update("alter table MyTable modify mySequencedValue int unsigned auto_increment");
    }
}

0

@Morten Berg'in benim için daha iyi çalışan kabul edilmiş çözümünün yanında bir alternatif sunmak istiyorum.

Bu yaklaşım, alanın gerçekte istenen Numbertipte - Longbenim kullanım durumumda - tanımlanmasını sağlar GeneralSequenceNumber. Bu, örneğin JSON (de-) serileştirme için yararlı olabilir.

Dezavantajı, biraz daha fazla veritabanı yükü gerektirmesidir.


İlk olarak, türün ActualEntityotomatik olarak artmasını istediğimiz bir şeye ihtiyacımız var :generatedLong

// ...
@Entity
public class ActualEntity {

    @Id 
    // ...
    Long id;

    @Column(unique = true, updatable = false, nullable = false)
    Long generated;

    // ...

}

Sonra, yardımcı bir varlığa ihtiyacımız var Generated. Paketin ActualEntitybir uygulama detayını saklamak için paketin yanına yerleştirdim :

@Entity
class Generated {

    @Id
    @GeneratedValue(strategy = SEQUENCE, generator = "seq")
    @SequenceGenerator(name = "seq", initialValue = 1, allocationSize = 1)
    Long id;

}

Son olarak, kaydetmeden önce takmak için bir yere ihtiyacımız var ActualEntity. Orada bir Generatedörnek oluşturur ve devam ederiz . Bu daha sonra idtürden oluşturulan bir veritabanı dizisi sağlar Long. Bu değeri,ActualEntity.generated .

Kullanım durumumda, bunu @RepositoryEventHandler, ActualEntitydevam etmeden hemen önce çağrılan bir Spring Data REST kullanarak uyguladım . İlkeyi göstermelidir:

@Component
@RepositoryEventHandler
public class ActualEntityHandler {

    @Autowired
    EntityManager entityManager;

    @Transactional
    @HandleBeforeCreate
    public void generate(ActualEntity entity) {
        Generated generated = new Generated();

        entityManager.persist(generated);
        entity.setGlobalId(generated.getId());
        entityManager.remove(generated);
    }

}

Gerçek hayattaki bir uygulamada test etmedim, bu yüzden lütfen dikkatli olun.


-1

Senin gibi bir durumda bulundum (@Id olmayan alan için JPA / Hazırda Bekleme dizisi) ve db şemamde insert üzerine benzersiz bir sıra numarası ekleyen bir tetikleyici oluşturdum. JPA / Hibernate ile çalışmayı hiç bulamadım


-1

Saat geçirdikten sonra, sorunumu çözmeme yardımcı oldu:

Oracle 12c için:

ID NUMBER GENERATED as IDENTITY

H2 için:

ID BIGINT GENERATED as auto_increment

Ayrıca yap:

@Column(insertable = false)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.