SparkJavaと互換性が休止状態?

ヴァル:

私は遅延ロードモードでSparkJavaで休止状態を使用してエラーを持っています。

それはSparkJavaせずに正常に動作しているが、SparkJavaを使用した場合には、OneToMany関係のために熱心なロードを強制しようとしています。


- モデル

@Entity
@Table(name = "KU_SUPPLIER")
public class Supplier {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @NotEmpty(message = "Please provide a name")
    private String name;

    @OneToMany(mappedBy = "supplier")
    private List<Item> items;  // Should be lazy-loaded

    // Constructor / Getters / Setters
}


- DAO

public class SupplierDao implements Dao<Supplier> {

    private final SessionFactory sessionFactory;

    public SupplierDao(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @Override
    @SuppressWarnings("unchecked")
    public List<Supplier> findAll() {
        try (Session session = sessionFactory.openSession()) {
            return session.createQuery("FROM com.seafrigousa.model.Supplier").getResultList();
        }
    }
}


- メイン

// Working perfectly and lazy-load Items as desired    
supplierDao.findAll();

// The method will be called when a web browser goes to "localhost/suppliers"
// It throws org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: model.Supplier.items, could not initialize proxy - no Session
get("/suppliers", "application/json", supplierDao::findAll);


私はDAOからセッションを閉じていないことで確認し、私はそれがEAGERロードモードにあったかのように、2つの選択、サプライヤー用とアイテムのための1つを実行していたので、Hibernateは、クエリを実行していたことがわかりました。

この現象の理由はありますか?

ありがとうございました!

Tijkijiki:

私はここでそれを推測:get("/suppliers", "application/json", supplierDao::findAll);あなたは、JSONにサプライヤーのオブジェクトをシリアル化しています。Itemsフィールドには、そのセッションのうち、遅延初期化の原因、その値を取得し、直列化から除外としてマークされた(またはセッションがクローズされていない場合は、アイテムのために2番目のクエリをredundand)されていません。

私の推測が正しければ、あなたのシリアライザは、アイテムのフィールドを無視するか、またはあなたのクエリでそれらを取得します

session.createQuery("FROM com.seafrigousa.model.Supplier s join fetch s.items").getResultList();

あなたはオプションを以下しているシリアライザとしてgsonを使用します:

  1. @Exposeあなたはフィールド上の注釈たいシリアライズします。

    @Entity
    @Table(name = "KU_SUPPLIER")
    public class Supplier {
    
        @Expose
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private int id;
    
        @Expose
        @NotEmpty(message = "Please provide a name")
        private String name;
    
        @OneToMany(mappedBy = "supplier")
        private List<Item> items;  // Should be lazy-loaded
    
        // Constructor / Getters / Setters
    }
    

    次gson開始と

    Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
    
  2. カスタム注釈FeをExclusionStrategy

    public class IgnoreFieldExclusionStrategy implements ExclusionStrategy {
    
        @Override
        public boolean shouldSkipField(FieldAttributes fieldAttributes) {
            return fieldAttributes.getAnnotation(GsonIgnore.class) != null;
        }
    
        @Override
        public boolean shouldSkipClass(Class<?> aClass) {
            return false;
        }
    }
    

    カスタム注釈付き @GsonIgnore

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

    そして、gson開始

    Gson gson = new GsonBuilder().addSerializationExclusionStrategy(new IgnoreFieldExclusionStrategy()).create();
    

    あなたのクラスは次のようになります。

    @Entity
    @Table(name = "KU_SUPPLIER")
    public class Supplier {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private int id;
    
        @NotEmpty(message = "Please provide a name")
        private String name;
    
        @GsonIgnore
        @OneToMany(mappedBy = "supplier")
        private List<Item> items;  // Should be lazy-loaded
    
        // Constructor / Getters / Setters
    }
    

あなたが必要シリアライズを持っている希望の場合Supplieritems異なるAPIで、あなたがのためにDTOオブジェクトを作成することができますSupplierし、このような結果から、それをマッピングします。

package com.seafrigousa.dto

public class SupplierDTO {

    private int id;
    private String name;

    public SupplierDTO(int id, String name) {
        this.id = id;
        this.name = name;
   }

    // Getters / Setters
}

そして、クエリ:

session.createQuery("select new com.seafrigousa.dto.SupplierDTO(s.id, s.name) FROM com.seafrigousa.model.Supplier s").getResultList();

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=210717&siteId=1