2016-12-03 8 views
0

通貨を変換するJava EEアプリケーションを作成しました。ユーザーは変換する値、「元」通貨、および「to」通貨を入力し、データベース表から変換率を取得します。JPQLを使用してデータベースから行データを取得

! [NetBeansでテーブルの断片] https://s16.postimg.org/8m242gyyd/Screen_Shot_2016_12_03_at_23_45_23.png

マイ通貨コントローラは、次のコードを持っている:

public double convertTo(double value, String fromCur, String toCur) { 
    TypedQuery<Rate> query = em.createQuery("" 
      + "SELECT c FROM Rate c WHERE c.fromCur = 'BRA' AND c.toCur = 'EUR'", Rate.class); 

    query.setParameter("tocurrency", toCur); 
    query.setParameter("fromcurrency", fromCur); 

    Rate result = query.getSingleResult(); 

    if (result == null) { 
     throw new EntityNotFoundException("Can't find rate"); 
    } 

    return value * result.getValue(); 

} 

私の目標は、例えば、「EUR」に「BRA」から速度を取得し、変換量を計算することですそれを返す。私は、アプリケーションを実行すると、私は例外を取得:

は、getSingleResult()任意のエンティティ

を取得できませんでしたが

エンティティマネージャを使用して、この変換を計算するために、データベースからレートを取得するための簡単な方法がなければなりません私はそれのための適切なクエリメソッドまたはJPAソリューションを見つけることができません。助言がありますか?

Rate.javaは以下であるJavaエンティティへのコード:

package currency.model; 

import java.io.Serializable; 
import java.math.BigDecimal; 
import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.Id; 

/** 
* 
* @author teowey 
*/ 
@Entity 
public class Rate implements ConversionDTO, Serializable { 


@Id 
@GeneratedValue 
private Integer conversionid; 

private double rate; 
private BigDecimal value; 

private String fromCur; 
private String toCur; 
/** 
* Creates a new instance of Account 
*/ 
public Rate() { 
} 

@Override 
public Integer getConversionId() { 
    return conversionid; 
} 

public void setConversionId(Integer conversionid) { 
    this.conversionid = conversionid; 
} 
@Override 
public BigDecimal getValue() { 
    return value; 
} 

public void setRate(double rate) { 
    this.rate = rate; 
} 

public double getRate(String conversion) { 
    return rate; 
} 

public String getFromCur() { 
    return fromCur; 
} 

public void setFromCur(String from) { 
    this.fromCur = from; 
} 

public String getToCur() { 
    return toCur; 
} 

public void setToCur(String to) { 
    this.toCur = to; 
} 

} 
+0

この例外が発生した場合、探している行が存在しないことを意味します。たぶんあなたは別のテーブルやスキーマを照会しているかもしれません。あるいは、データベースに加えられた変更をコミットしなかったかもしれません。 –

+0

問題はデータベースではなく、私はすべて正しく構成されています。スクリーンショットには、通貨BRAとその最初の行の通貨EURのテーブルがあります。私の問題は、ロールからデータを取得し、Entityオブジェクト(Rate)に入れてメソッドの値として使用することです。私が使用しているJPQLクエリは正しいものではありません。使用するクエリーとエンティティマネージャメソッドを理解するのは苦労しています。 – teowey

+0

エンティティのコードを投稿していないので、そこにバグを見つけることは難しいです。クエリにはパラメータもありませんが、パラメータを渡しています。しかし、クエリが無効な場合、別の例外が発生します。例外は、クエリが実行されたが、何も返されていないことを明確に示しています。 –

答えて

0

は、問題の原因コード内の小さな問題があったかどうかを確認しようとしましたが、1つを見つけることができませんでした。

ここでは、いくつかのノートとデバッグコードを使ってテストする方法を示します。

// changed input amount to big decimal to avoid floating point issues 
public BigDecimal convertTo(String from, String to, BigDecimal value) { 

    // changed to validate the currency code - note BRA will fail - need to change to BRL - remove this code if you dont need it. 
    Currency fromCurr = Currency.getInstance(from); 
    Currency toCurr = Currency.getInstance(to); 

    // debugging code - to help troubleshoot (only use this on small table) - will print out the contents of the table so you can see if data is not correct 
    List<Rate> rates = em.createQuery("SELECT c FROM Rate c", Rate.class).getResultList(); 
    if (rates == null || rates.isEmpty()) { 
     throw new RuntimeException("rates table is empty"); 
    } 

    for (Rate r : rates) { 
     // push to sysout or whatever logger you are using 
     System.out.println(String.format("Rate:fromCur[%s], toCur[%s]", r.getFromCur(), r.getToCur())); 
    } 
    // end debugging code - remove when no longer needed. 

    // changed the query to use bind parameters - :fromCurrency, :toCurrency 
    TypedQuery<Rate> query = em.createQuery(
      "SELECT c FROM Rate c WHERE c.fromCur = :fromCurrency AND c.toCur = :toCurrency", Rate.class); 

    query.setParameter("fromCurrency", fromCurr.getCurrencyCode()); 
    query.setParameter("toCurrency", toCurr.getCurrencyCode()); 

    Rate rate = query.getSingleResult(); 
    if (rate == null) { 
     throw new EntityNotFoundException("Can't find rate"); 
    } 

    // changed to use big decimal, scale and rounding as well as avoid floating point issues 
    BigDecimal converted = 
      value.multiply(rate.getValue()).setScale(toCurr.getDefaultFractionDigits(), RoundingMode.HALF_DOWN); 

    return converted; 
} 

私は、潜在的な落とし穴を避けるために、通貨を処理する際の注意をいくつか挙げました。これがあなたの前進に役立つことを願っています

+0

ヘルプ@Bob Lukensのおかげで、テーブルのBRAをBRLに変更しました。私はあなたのテストを試みました、そして、私はもう何のエラーもありません、それは良いです。しかし、デバッグコード 'List rates = em.createQuery(" SELECT c FROM Rate c "、Rate.class).getResultList();からエンティティレートが空ではない正しく実装されました。 NetBeansでは警告が生成されず、ロジックは間違っている必要があります。 Rate.javaコード[リンク](https://github.com/teowey/currency-converter/blob/master/src/java/currency/model/Rate.java)へのリンク – teowey

+0

コードは正しく表示されます。エンティティマネージャとやりとりをするときには、大幅に異なる例外が発生するわけではありませんでした。 –

+0

これはpersistence.xmlでの問題である可能性があります: ''これはJPAにエンティティ内の情報を使用して毎回dbを再作成します。あなたがテーブルにデータを持っているか持っていれば、アプリを起動するたびにすべて削除されている可能性があります –

0

JPQLを使用してデータベースから行データまたはテーブルデータを取得してください JPQlクエリを実装するだけです。単純に私はthis.theをしました。私のテーブル名は農家で、classNameはFarmerです。私はデータベースの注釈を使用しました。

public static void main(String[] args) { 
    EntityManager entityMgr = getEntityManager(); 
    entityMgr.getTransaction().begin(); 
    Query q = entityMgr.createQuery("SELECT s FROM Farmer s"); 

    List<Farmer> list = q.getResultList(); 
    for(Farmer s:list) { 
     System.out.println("Id : "+s.getId()+" Farmer NAME : "+s.getName()+" location : "+s.getVillage()); 
     } 
    entityMgr.getTransaction().commit(); 
    entityMgr.clear(); 
} 
関連する問題