2012-10-05 13 views
5

Yeni bir nesnem var. Bunu kaydetmeden önce kimliği bilmek istiyorum. Mümkün mü? Yoksa bunun için başka bir yolu var mı? Jpa'yı orm ve oracle olarak veritabanı olarak kullanıyorum.jpa içinde bir nesneyi kaydetmeden önce kimliği nasıl öğrenirim?

@Id 
@Basic(optional = false) 
@Column(name = "ID", nullable = false) 
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "woTypeSeq") 
private Long id; 

Benim varlığımda bir kod alanım var. Kullanıcı code alanı için bir değer girmezse, kodu kimliğin kimliği olarak ayarlamak istiyorum. Varlığı devam ettirirsem, tabiki id olarak alabilirim ve kod değerini id olarak belirleyebilirim, ancak bu ek sorgu veritabanıdır.

Sana (aslında yazmadan önce) önceden bu değeri bilemez bir @GeneratedValue tipi id ile bu

if(entity.getCode()==null) { 
    entity.setCode(entity.getId); 
    jpaDao.saveOrUpdate(entity); 
} 
+1

Sen değeri almak için jeneratör kendiniz kullanabilir ve "elle" varlık olarak ayarlayın, @GeneratedValue önlemek olabilir – SJuan76

+0

ben yok Burada basit bir uygulamasıdır Bunu manuel olarak ayarlamak istiyorum.Oracle'den id için sonraki değeri aldım ve bunu yeni varlığın kimliğine ayarladım, bu mantıklı mı? – mstzn

cevap

5

Bu, sonunda bir çözüm buldum. Bir sonraki id veritabanı dizisi tarafından atanacaktır çünkü Aslında

, sen JPA sıra jeneratör kullanırsanız, kesinlikle, veritabanında kaydetmeden önce işletmenin kimliği alamıyor. Bir özel jeneratörü kullanırsanız

id elde etmek bir yolu vardır, kaydetmeden önce kimliği alabilirsiniz.id alanı için CustomGenerator kullanma

public class CustomGenerator extends IdentityGenerator implements Configurable { 

    private IdentifierGenerator defaultGenerator; 

    public Serializable generate(SessionImplementor session, Object object) throws HibernateException { 
     Long idValue = (Long)defaultGenerator.generate(session, object); 
     //idValue will be assigned your entity id 
     return idValue; 
    } 

    @Override 
    public void configure(Type type, Properties params, Dialect d) throws MappingException { 
     DefaultIdentifierGeneratorFactory dd = new DefaultIdentifierGeneratorFactory(); 
     dd.setDialect(d); 
     defaultGenerator = dd.createIdentifierGenerator("sequence", type, params); 
    } 
} 

:

@Id 
@Basic(optional = false) 
@Column(name = "ID", nullable = false) 
@GenericGenerator(name = "seq_id", strategy = "com.yoncabt.abys.core.listener.CustomGenerator", parameters = { @Parameter(name = "sequence", value = "II_FIRM_DOC_PRM_SEQ") }) 
@GeneratedValue(generator = "seq_id") 
private Long id; 
8

gibi bir şey yapmak istiyorum. Bununla birlikte, Bean'inizi sürdürdüğünüzde, id alanı bu fasülyede doldurulacak ve bunun için ekstra bir sorgulama yapmanıza gerek kalmadan elde edebilirsiniz. Başka bir deyişle: o kimliği almak için önce

MyEntiry myEnt = new MyEntity(); //the id field is null now 
entityManager.persist(myEnt);//the id field is populated in myEnt now 
Long id = myEnt.getId(); 

Ayrıca, EntityManager nasıl yapılandırıldığına bağlı olarak, aynı zamanda ilk işlem (el) işlemek gerekebilir. Yorumlarınız göre

Güncelleme

Eğer (JPA sürüm 2 kullanıyorsanız), JPA LifeCycle Dinleyiciler kullanabilirsiniz yakalamak ve onu kurtardı ve/veya güncellenmiş önce varlık için bir şeyler yapmak istiyorsanız: Handling JPA lifecycle event using listeners and callbacks .

Temel olarak, sizin fasulye bir validate() yöntemi yapmak @PrePersist ve @PreUpdate ile açıklama ve 2 yorum başına

Güncelleme (kod kimliğinin değerine boş kümesi bunu ise) o doğrulama yapabilirsiniz

Evet, dürüstçe şunu düşündüm: şimdi id otomatik olarak üretilirse, önceden ispat edilen olaydan sonra popülasyona girebilirdi, böylece önceden ispatlanmış kodunuz yürütüldüğünde hala kimliğin ne olduğunu bilmezsiniz (Ayrıca, örnekte bağlamanızın otomatik olarak DEĞİLDİR, ancak manuel olarak ayarlanmadığını da görebilirsiniz). Bu durumda yapabileceğiniz şey, isCodeEmpty adı verilen (@Transient no'lu açıklamalı olarak), sizin için bir boolean alanı eklemektir (bu, özellikle başlatılmamışsa varsayılan olarak yanlıştır). Ardından, @PrePersist açıklamalı yönteminde, kod alanı değerinin boş olup olmadığını kontrol edersiniz ve eğer varsa, boole değerini true olarak ayarlayın. Sonra bu boole kontrol edecektir (id alanını ayarlama kenara) öyle sizin setId(...) yöntemi refactor ve gerçek kümesi ise kimliği alanı o kadar kod alanının değeri: Uzun hakkında araştırma sonra

public class YourEntity { 

@Transient 
private boolean isCodeEmpty; 

public void setId(Whatever id) { 
this.id = id; 
if(isCodeEmpty) { 
    this.code = id; 
    //if necessary: 
    //this.isCodeEmpty = false; 
} 
} 

@PrePersist 
public void validate() { 
if(code == null || code.isEmpty()) { 
    isCodeEmpty = true; 
} 

} 


} 
+0

Cevapladığınız için teşekkür ederiz. Sorumu güncelledim. Kontrol ettiniz mi? – mstzn

+0

Ben prepersist id değeri entity dinleyici.but denedim null.Null null olduğunu bilmiyorum.Bu gibi uygular = http://www.java2s.com/Tutorial/Java/0355__JPA/EntityListenersPrePersist.htm var mı öneri veya fikir? Çok teşekkürler – mstzn

+1

senin fikrin mükemmel ama prePersist setId() yöntemi çalıştıktan sonra. Ne dediğini yaptım. Ben hata ayıklama, ancak setId yöntemi uygulanmadı ve kod alanı ayarlanmadı.Prepersist çalışıyor. – mstzn

İlgili konular