2017-09-22 53 views
8

Kotlin ile Hazırda Beklet özelliğini kullanıyorum veile @ManyToOne arasındaki ilişkilerde sorun yaşıyorum. Aşağıdaki düşünün:Kotlin ile hazırda bekletme: @ManyToOne (fetch = FetchType.LAZY)

@ManyToOne(fetch = FetchType.LAZY) 
open var event: Event? 

sorun FetchType.LAZY kullanıldığında, getirilen Event Üzerinde JavaassistLazyInitializer ile sınıfının Event_$$_jvst_... olacak olmasıdır. Ancak etkinlik hiçbir zaman başlatılamayacak, her şey boş ya da boş olacak.

  1. FetchType.LAZY kaldırıldıktan sonra, her şey düzgün çalışır.
  2. Bu, Java'da gerçekleşmedi.
  3. var eklemeye çalıştım, böylece Event doğru şekilde proxy edilebilir. Etkisi yok.
  4. @Entity sınıflarının hepsi de open dersidir. open anahtar kelimesi kaldırılırsa, proxy oluşturulmaz ve bu nedenle tembellik olmaz.

Tahminim, Hazırda bekletme, bu varsayılan kotlin alıcılarını kolayca proxy yapamaz. Bunu çözmenin bir yolu var mı?

cevap

0

Eğer sorunu kontrol etmek Ben basit bir örnek yazmak varlığınızı

/** 
* Utility method that tries to properly initialize the Hibernate CGLIB 
* proxy. 
* @param <T> 
* @param maybeProxy -- the possible Hibernate generated proxy 
* @param baseClass -- the resulting class to be cast to. 
* @return the object of a class <T> 
* @throws ClassCastException 
*/ 
public static <T> T deproxy(Object maybeProxy, Class<T> baseClass) throws ClassCastException { 
    if (maybeProxy instanceof HibernateProxy) { 
     return baseClass.cast(((HibernateProxy) maybeProxy).getHibernateLazyInitializer().getImplementation()); 
    } 
    return baseClass.cast(maybeProxy); 
} 
0

deproxy için bu statik yöntemi kullanabilir ve tüm iyi çalışıyor.

import org.hibernate.CacheMode 
import org.hibernate.Session 
import org.hibernate.SessionFactory 
import org.hibernate.Transaction 
import org.hibernate.boot.MetadataSources 
import org.hibernate.boot.registry.StandardServiceRegistryBuilder 
import org.hibernate.cfg.Environment 
import java.util.* 
import javax.persistence.* 


fun main(args: Array<String>) { 
    val standardServiceRegistryBuilder = StandardServiceRegistryBuilder() 

    val settings = HashMap<String, String>().apply { 
     put(Environment.DRIVER, "org.h2.Driver") 
     put(Environment.URL, "jdbc:h2:mem:myDb;DB_CLOSE_DELAY=-1") 
     put(Environment.USER, "sa") 
     put(Environment.PASS, "sa") 
     put(Environment.DIALECT, "org.hibernate.dialect.H2Dialect") 
     put(Environment.SHOW_SQL, "true") 
     put(Environment.HBM2DDL_AUTO, "create") 
    } 

    val sessionFactory = standardServiceRegistryBuilder.applySettings(settings) 
      .build() 
      .let { 
       MetadataSources(it).apply { 
        addAnnotatedClass(History::class.java) 
        addAnnotatedClass(Event::class.java) 
       } 
      } 
      .run { metadataBuilder.build() } 
      .run { sessionFactoryBuilder.build() } 

    sessionFactory.inSession { 
     inTransaction { session -> 
      session.save(Event(1, "event description")) 

      session.save(History(1, Event(1), "history description")) 
     } 
    } 

    sessionFactory.inSession { 
     inTransaction { session -> 
      val entity = session.get(Event::class.java, 1L) 

      println("=============1=============") 
      println(entity) 
     } 
    } 

    sessionFactory.inSession { 
     inTransaction { session -> 
      val entity = session.load(History::class.java, 1L) 

      println("=============2=============") 
      println(entity) 
     } 
    } 
} 

private fun SessionFactory.inSession(function: Session.() -> Unit) { 
    val session = this.openSession() 

    session.function() 

    session.close() 
} 

private fun Session.inTransaction(function: Transaction.(s: Session) -> Unit) { 
    val transaction = this.beginTransaction() 

    transaction.function(this) 

    transaction.commit() 
} 

@Entity 
open class History(
     @Id 
     open var id: Long? = null, 

     @ManyToOne(fetch = FetchType.LAZY) 
     @JoinColumn(name = "eventId") 
     open var event: Event? = null, 

     open var description: String = "" 
) { 
    override fun toString(): String { 
     return "History(id=$id, event=$event, description='$description')" 
    } 
} 

@Entity 
open class Event(
     @Id 
     open var id: Long? = null, 
     open var description: String? = null, 

     @OneToMany(fetch = FetchType.LAZY, mappedBy = "event") 
     open var history: MutableSet<History>? = null 
) { 
    override fun toString(): String { 
     return "Event(id=$id, description='$description', history=${history?.size})" 
    } 
} 

Kayıtlar şuna benzer:

2017-12-05 18:43:03 [main] INFO org.hibernate.Version - HHH000412: Hibernate Core {5.2.12.Final} 
2017-12-05 18:43:03 [main] INFO org.hibernate.cfg.Environment - HHH000206: hibernate.properties not found 
2017-12-05 18:43:03 [main] INFO o.h.annotations.common.Version - HCANN000001: Hibernate Commons Annotations {5.0.1.Final} 
2017-12-05 18:43:04 [main] WARN o.hibernate.orm.connections.pooling - HHH10001002: Using Hibernate built-in connection pool (not for production use!) 
2017-12-05 18:43:04 [main] INFO o.hibernate.orm.connections.pooling - HHH10001005: using driver [org.h2.Driver] at URL [jdbc:h2:mem:myDb;DB_CLOSE_DELAY=-1] 
2017-12-05 18:43:04 [main] INFO o.hibernate.orm.connections.pooling - HHH10001001: Connection properties: {password=****, user=sa} 
2017-12-05 18:43:04 [main] INFO o.hibernate.orm.connections.pooling - HHH10001003: Autocommit mode: false 
2017-12-05 18:43:04 [main] INFO o.h.e.j.c.i.DriverManagerConnectionProviderImpl - HHH000115: Hibernate connection pool size: 20 (min=1) 
2017-12-05 18:43:04 [main] INFO org.hibernate.dialect.Dialect - HHH000400: Using dialect: org.hibernate.dialect.H2Dialect 
2017-12-05 18:43:04 [main] INFO o.h.validator.internal.util.Version - HV000001: Hibernate Validator 5.3.5.Final 
WARNING: An illegal reflective access operation has occurred 
WARNING: Illegal reflective access by javassist.util.proxy.SecurityActions (file:/Users/evgenyzaharov/.gradle/caches/modules-2/files-2.1/org.javassist/javassist/3.20.0-GA/a9cbcdfb7e9f86fbc74d3afae65f2248bfbf82a0/javassist-3.20.0-GA.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) 
WARNING: Please consider reporting this to the maintainers of javassist.util.proxy.SecurityActions 
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations 
WARNING: All illegal access operations will be denied in a future release 
Hibernate: drop table Event if exists 
2017-12-05 18:43:04 [main] INFO org.hibernate.orm.connections.access - HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.[email protected]56913163] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode. 
Hibernate: drop table History if exists 
Hibernate: create table Event (id bigint not null, description varchar(255), primary key (id)) 
2017-12-05 18:43:04 [main] INFO org.hibernate.orm.connections.access - HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.[email protected]e8e0dec] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode. 
Hibernate: create table History (id bigint not null, description varchar(255), eventId bigint, primary key (id)) 
Hibernate: alter table History add constraint FK2yaqfgh2x1lsxcpbuifmd245k foreign key (eventId) references Event 
2017-12-05 18:43:04 [main] INFO o.h.t.s.internal.SchemaCreatorImpl - HHH000476: Executing import script 'org.hiber[email protected]6c15e8c7' 
Hibernate: select event_.id, event_.description as descript2_0_ from Event event_ where event_.id=? 
Hibernate: insert into Event (description, id) values (?, ?) 
Hibernate: insert into History (description, eventId, id) values (?, ?, ?) 
Hibernate: update History set description=?, eventId=? where id=? 
Hibernate: select event0_.id as id1_0_0_, event0_.description as descript2_0_0_ from Event event0_ where event0_.id=? 
=============1============= 
Hibernate: select history0_.eventId as eventId3_1_0_, history0_.id as id1_1_0_, history0_.id as id1_1_1_, history0_.description as descript2_1_1_, history0_.eventId as eventId3_1_1_ from History history0_ where history0_.eventId=? 
Event(id=1, description='event description', history=1) 
=============2============= 
Hibernate: select history0_.id as id1_1_0_, history0_.description as descript2_1_0_, history0_.eventId as eventId3_1_0_ from History history0_ where history0_.id=? 
Hibernate: select event0_.id as id1_0_0_, event0_.description as descript2_0_0_ from Event event0_ where event0_.id=? 
Hibernate: select history0_.eventId as eventId3_1_0_, history0_.id as id1_1_0_, history0_.id as id1_1_1_, history0_.description as descript2_1_1_, history0_.eventId as eventId3_1_1_ from History history0_ where history0_.eventId=? 
History(id=1, event=Event(id=1, description='event description', history=1), description='history description') 

Lazy başlatma sadece açık bir değeri aldıktan sonra saha verilerini yüklemek başlar.

Bu yardımcı olur umarım.

İlgili konular