Modelim aşağıdaki gibidir. Burda önemli olan nokta entity olmamasıdır.

   public class MyUser{
        private String name;
         private String surname;
          private String phone;

          /* getter and setter*/
    }

Aşağıdaki kod parçasını çalıştırdığımda

EntityManager em=ym.getEntityManager();
Query query= em.createNativeQuery("select name,surname,phone from TblUser");

// alttaki kullanımıda denedim sonuç değişmedi
// Query query= em.createNativeQuery("select name,surname,phone from TblUser",MyUser.class);

List<MyUser> list= query.getResultList();

Burda getResultList metodu Object[] listesi döndürüyor ayrıca her bir satıra ait bilgileri dizi olarak döndürmektedir. Reflection ile veriyi alıp kendi objeme doldurmak istediğimde kolon bilgileri olmadığı için bu yöntem işe yaramıyorum. Sırası ile değerleri doldurayım desem. MyUser objemdeki bir kolon select sorgusu ile çekilmemiş ise yanlış bir alana değer koymuş olurum.

Aşağıdaki linkte anlatılanıda denedim fakat sonun değişmiyor. http://docs.oracle.com/javaee/7/api/javax/persistence/ConstructorResult.html http://stackoverflow.com/questions/17708946/jpa-native-query-select-and-cast-object

MyUser objesine(Entity olmayan bir objeye) değerlerin setlenmesi için nasıl bir yol izlemeliyim.

soruldu: 06 Haz '14, 09:20

M%C3%BCsl%C3%BCm%20%C3%96ZT%C3%9CRK's gravatar image

Müslüm ÖZTÜRK
10.6k103690
cevap kabul oranı: 28%

JPA ile amacıma ulaşamayacağımı anladım ve JDBC ile veriyi çekip Reflection ile objeme doldurma yöntemini seçtim. Aşağıdaki metodu oluşturdum. Type' lar için if kullanmak hoşuma gitmedi acaba daha efektif bir yolu var mıdır?

public List<Object> runNativeQuery(YazEm ym, String sql, List<NativeParameter> params, Class type) throws Exception {

boolean transactionActived = ym.transactionIsActive();
        if (!transactionActived) {
            ym.transactionBegin();
        }

Connection con = null;
        try {
            con = DriverManager.getConnection(ym.url, ym.username, ym.password);
            java.sql.PreparedStatement stmt = con.prepareStatement(sql);

for (NativeParameter p : params) {
                if (p.type.equals(Integer.class) || p.type.equals(int.class)) {
                    stmt.setInt(p.order, Integer.parseInt(p.value.toString()));
                } else if (p.type.equals(Double.class) || p.type.equals(double.class)) {
                    stmt.setDouble(p.order, Double.parseDouble(p.value.toString()));
                } else if (p.type.equals(Float.class) || p.type.equals(float.class)) {
                    stmt.setFloat(p.order, Float.parseFloat(p.value.toString()));
                } else if (p.type.equals(Long.class) || p.type.equals(long.class)) {
                    stmt.setLong(p.order, Long.parseLong(p.value.toString()));
                } else if (p.type.equals(java.sql.Date.class)) {
                    stmt.setDate(p.order, Date.valueOf(p.value.toString()));
                } else {
                    stmt.setString(p.order, p.value.toString());
                }
            }

ResultSet resultSet = stmt.executeQuery();

List<Object> list = new ArrayList<Object>();

while (resultSet.next()) {
                Object obj = type.newInstance();
                SetObj(obj, resultSet);
                list.add(obj);
            }
            con.close();
            return list;
        } catch (Exception ex) {
            YazConsole.WriteConsole("runNativeQuery çalışma hatası. Hata:" + ex, BaseRepository.class);
            return null;
        } finally {
            if (con != null) {
                if (con.isClosed()) {
                    con.close();
                }

if (!transactionActived) {
                    ym.transactionCommit();
                }
            }
        }

}

public <T> void SetObj(T obj, ResultSet resultSet) {

try {
            Field[] fields = obj.getClass().getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                // Eger IgnoreMapping annotation'u varsa bu field setlenmez
                Annotation annoIgnore = field.getAnnotation(IgnoreMapping.class);
                if (annoIgnore == null) {

String fieldName = field.getName();

Annotation anno = field.getAnnotation(ColumnName.class);
                    if (anno != null) {
                        ColumnName colName = (ColumnName) anno;
                        fieldName = colName.name();
                    }

Object value = resultSet.getObject(fieldName);
                    Class<?> type = field.getType();
                    if (type.equals(Integer.class) || type.equals(int.class)) {
                        field.set(obj, Integer.valueOf(String.valueOf(value)));
                    } else if (type.equals(Long.class) || type.equals(long.class)) {
                        field.set(obj, Long.valueOf(String.valueOf(value)));
                    } else if (type.equals(Double.class) || type.equals(double.class)) {
                        field.set(obj, Double.valueOf(String.valueOf(value)));
                    } else if (type.equals(Float.class) || type.equals(float.class)) {
                        field.set(obj, Float.valueOf(String.valueOf(value)));
                    } else if (type.equals(java.sql.Date.class)) {

field.set(obj, java.sql.Date.valueOf(String.valueOf(value)));
                    } else {
                        field.set(obj, String.valueOf(value));
                    }
                }

}
        } catch (Exception e) {
            System.out.println("Hata: " + e);
        }

}
(24 Haz '14, 02:39) Müslüm ÖZTÜRK M%C3%BCsl%C3%BCm%20%C3%96ZT%C3%9CRK's gravatar image

Sanirim sql query yanlis yazilmis. Basit bir JPA-List icin reflection kullanamanizi tavsiye etmem. Su sekilde yazarsaniz calismasi lazim:


String sql = "select * from VeritabanindakiTableAdi";
List<myuser> list = entityManager.createNativeQuery(sql, User.class).getResultList();
Ayrica Entity Manager ile query kullaniyorsaniz model objeniz Entity Bean olmali!. Eger POJO modeller kullaniyorsaniz Persistence Layer'den ayri Service Layer kisminda obje donusumlerini yazmaniz daha mantikli. Bu tur isler icin Dozer gibi Bean Mapper kullanilabilir.(http://dozer.sourceforge.net/)

(25 Haz '14, 10:31) CemIkta ♦ CemIkta's gravatar image

Cem bey benim amacım entity olmayan bir objeye native query ile değerleri doldurmak. Eğer entity ise objem böyle bir sorun yaşamıyorum.

(25 Haz '14, 11:39) Müslüm ÖZTÜRK M%C3%BCsl%C3%BCm%20%C3%96ZT%C3%9CRK's gravatar image

JPA kullanildigi zaman, jdbc yi cagirmak pek mantikli degil.

Bunun icin daha güzel bir yöntem söyle olabilir.

  1. Dynamic instantiation

Hibernate. 11.5. The SELECT clause

Liste icin örnek.

select new list(mother, offspr, mate.name)
from DomesticCat as mother
inner join mother.mate as mate
left outer join mother.kittens as offspr

Obje icin örnek:

select new Family(mother, mate, offspr)
from DomesticCat as mother
join mother.mate as mate
left join mother.kittens as offspr

Örnekler Hibernate den alindigi icin HQL ile yazilmistir. JPA da cok kücük bir fark olabilir.

permanent link

cevaplandı: 25 Haz '14, 19:21

mahmut_can's gravatar image

mahmut_can ♦
2.9k62552
cevap kabul oranı: 67%

1

Öncelikle deneme şansım olmadı ama aklıma gelen bir soru oluştu. performansı konusunda bir fikriniz var mı acaba? Birde Eclipse Link kullanıyorum ondada çalışıyor mu bilginiz var mı? Teşekkürler..

(26 Haz '14, 01:06) Müslüm ÖZTÜRK M%C3%BCsl%C3%BCm%20%C3%96ZT%C3%9CRK's gravatar image

Hibernate yada Eclipse link gibi (ORM) araçları kullanmak genelde performansı düşürür (converting işlemi yaptığı için) ama birkaç yıl önceki araştırlamarımda EclipseLink in Hibernate den daha hızlı sorgular atabildiğini okumuştum.

(26 Haz '14, 04:00) cherry cherry's gravatar image

Genelde performansi düsürür diye ifade kullanmak bence yanlis. Convert islemini öylede böylede yapman gerekecektir.

Performans problemi ciktigi zaman arastirmasini yapip ihtiyaca göre islemlerin yapilmasi daha mantikli.


Eclipse Link de calisiyor mu diye bir soru sorulmus. JPA kullandigin yerde calisir. EclipseLinki JPA olmadan kullanirsan, onun icin de buna benzer bir yöntem vardir mutlaka.

(26 Haz '14, 10:16) mahmut_can ♦ mahmut_can's gravatar image

/* Boyle denermisin. Student adinda Entitim var. Native yapdigin zaman fieldleri bir bir almak zorundasin.Bunun icinde bir pojo acdim Telebe adinda. Sonrasinda name,surname sirasiyla Telebe pojosuna doldur,sonda liste add et.

public List<object[]> students() {

    String sql = "Select name,surname from student";
    Query q = getEntityManager().createNativeQuery(sql);
    return (List<Object[]>) q.getResultList(); 
}

  @EJB
StudentFacadeLocal studentFacadeLocal;
List<Telebe> tList = new ArrayList<>();

private List<Telebe> stuList() {
    Telebe telebe;
    List<Telebe> list = new ArrayList<Telebe>();
    List<Object[]> objects = studentFacadeLocal.students();
    for (Object[] obj : objects) {
        telebe = new Telebe();
        telebe.setName((String) obj[0]);
        telebe.setSurname((String) obj[1]);
        tList.add(telebe);
    }
    return tList;
}

*/

permanent link

cevaplandı: 06 Haz '14, 11:21

mehmanbashirov's gravatar image

mehmanbashirov
211253138
cevap kabul oranı: 16%

değiştirildi: 06 Haz '14, 11:22

uygulamamdaki kod aynen böyle çalışıyor zaten ama daha iyisini bulabilmek adına bu soruyu açmıştım açıkcası :). Amacım daha genel bir metod yazıp göndediğim her sorguya göre objenin değerlerinin setlensini sağlamak.

(06 Haz '14, 11:38) Müslüm ÖZTÜRK M%C3%BCsl%C3%BCm%20%C3%96ZT%C3%9CRK's gravatar image

Reflection kullanabilirsiniz ama pek akıl işi bir yöntem değil ;) Repository pattern'i kullanmanız daha mantıklı olur. site içinde aratırsanız bulursunuz, pattern'e dair yazı.

(06 Haz '14, 11:41) Turgay Can Turgay%20Can's gravatar image

Şuan bir java framework'ü geliştiriyorum tabiri caizse reflectionlar havada uçuşuyor fakat burda sorun şu gelen veri Object[] dizisi ve her bir satırsa da object[] dizisi doğal olarak objemdeki field ile gelen verideki değerleri eşleştiremiyorum. @mehmanbeshirov arkadaşında gösterdiği gibi obj[0],obj[1] alanları ile objemdeki fieldları eşleştirmem sorgudaki sıralamaya bağlı oluyor, select ad,soyad from TblUser ile select soyad,ad from TblUser sorgusu objem ile map edemiyorum. Biraz karışık oldu sanırım ama derdim özetle bu...

(06 Haz '14, 12:07) Müslüm ÖZTÜRK M%C3%BCsl%C3%BCm%20%C3%96ZT%C3%9CRK's gravatar image
Cevabınız
toggle preview

powered by BitNami OSQA