Archive

Posts Tagged ‘java’

Testing JPA, Hibernate, JoSQL and Lucene

December 17, 2008 1 comment

(download the project file : change to .zip before opening)

This a just for showing some different way of making a simple query.

By the way I know that these simple tests can’t be seen seen as serious bencharking but at least it shows that using JoSQL on in memory data can enhance performance, if this make sens in your app to keep the data in memory. These are the results from the JoSQL test :

items count : 1680
JoSQL query run total time = 15 ms
JPA query run total time = 609 ms

Queries with Hibernate :

    /**
     * Simple Hibernate examples with queries
     *
     * Output :
     *
     * Hibernate: select fund0_.FUND_ID as FUND1_0_, fund0_.ADMINISTRATOR_ID as ADMINIST2_0_, fund0_.ADVISORY_NAME as ADVISORY3_0_, fund0_.ANNUAL_AUDIT as ANNUAL4_0_, fund0_.AUDIT_FIRM as AUDIT5_0_, fund0_.auditor as auditor0_, fund0_.banker as banker0_, fund0_.CLASSIFICATION_ID as CLASSIFI8_0_, fund0_.codification as codifica9_0_, fund0_.COMM_STATUS as COMM10_0_, fund0_.COUNTRY_OF_DOMICILE_ID as COUNTRY11_0_, fund0_.DATA_VENDOR_FUND_ID as DATA12_0_, fund0_.DATA_VENDOR_ID as DATA13_0_, fund0_.deleted as deleted0_, fund0_.DISCLOSURE_ID as DISCLOSURE15_0_, fund0_.EXTCOM_AGREEMENT as EXTCOM16_0_, fund0_.FINANCIAL_AUTHORITY_ID1 as FINANCIAL17_0_, fund0_.FINANCIAL_AUTHORITY_ID2 as FINANCIAL18_0_, fund0_.FINANCIAL_AUTHORITY_ID3 as FINANCIAL19_0_, fund0_.FISCAL_YEAR_END as FISCAL20_0_, fund0_.FUND_CAPACITY as FUND21_0_, fund0_.FUND_DESCRIPTION as FUND22_0_, fund0_.FUND_NAME as FUND23_0_, fund0_.FUND_REDEMPTION_GATE_FUND_LVL as FUND24_0_, fund0_.FUND_REDEMPTION_GATE_IND_LVL as FUND25_0_, fund0_.GEOGRAPHICAL_FOCUS_ID as GEOGRAP26_0_, fund0_.inception as inception0_, fund0_.instruments as instrum28_0_, fund0_.internal as internal0_, fund0_.INVESTMENT_RESTRICTIONS as INVESTMENT30_0_, fund0_.INVESTMENT_STATUS_ID as INVESTMENT31_0_, fund0_.INVESTMENT_STRATEGY as INVESTMENT32_0_, fund0_.INVESTMENT_SUB_STATUS_ID as INVESTMENT33_0_, fund0_.ISO_CODE as ISO34_0_, fund0_.IVT_MANAGEMENT_FIRM_ID as IVT35_0_, fund0_.LAST_AUDIT as LAST36_0_, fund0_.LAST_DUE_DILIGENCE as LAST37_0_, fund0_.LEGAL_ADVISOR_ID1 as LEGAL38_0_, fund0_.LEGAL_ADVISOR_ID2 as LEGAL39_0_, fund0_.LEGAL_ADVISOR_ID3 as LEGAL40_0_, fund0_.LEGAL_ADVISOR_OFFSHORE as LEGAL41_0_, fund0_.LEGAL_COUNSEL as LEGAL42_0_, fund0_.LEGAL_DESCRIPTION as LEGAL43_0_, fund0_.LEGAL_DESCRIPTION_ID as LEGAL44_0_, fund0_.LISTED_ON_A_STOCK_EXCHANGE as LISTED45_0_, fund0_.MANAGED_ACCOUNT as MANAGED46_0_, fund0_.MANAGEMENT_FIRM_ID as MANAGEMENT47_0_, fund0_.MARKETING_NAME as MARKETING48_0_, fund0_.MASTER_FUND_ID as MASTER49_0_, fund0_.MASTER_FUND_NAME as MASTER50_0_, fund0_.OFFSHORE_NAME as OFFSHORE51_0_, fund0_.OFFSHORE_VEHICLE as OFFSHORE52_0_, fund0_.PLACEMENT_AGENT as PLACEMENT53_0_, fund0_.PRIMARY_SHARE as PRIMARY71_0_, fund0_.PTF_MANAGEMENT_FIRM_ID as PTF54_0_, fund0_.ranking as ranking0_, fund0_.REPORTING_FREQUENCY_ID as REPORTING56_0_, fund0_.REPORTING_FREQUENCY_OTHER as REPORTING57_0_, fund0_.RISK_POLICY as RISK58_0_, fund0_.SECTOR_FOCUS_ID as SECTOR59_0_, fund0_.SIDE_POCKET_ALLOWABLE as SIDE60_0_, fund0_.source as source0_, fund0_.SS_CLASSIFICATION_ID as SS62_0_, fund0_.SS_FOF_CLASSIFICATION_ID as SS63_0_, fund0_.SS_MS_CLASSIFICATION_ID as SS64_0_, fund0_.stage as stage0_, fund0_.status as status0_, fund0_.STATUS_ID as STATUS67_0_, fund0_.SUB_STRATEGY as SUB68_0_, fund0_.updated as updated0_, fund0_.updater as updater0_ from Fund fund0_
     * fund list size = 1680
     * Hibernate: select count(fund0_.FUND_ID) as col_0_0_ from Fund fund0_
     * fund list size = 1680
     * Hibernate: select fundshare0_.SHARE_ID as SHARE1_1_, fundshare0_.ACCESS_RIGHT as ACCESS2_1_, fundshare0_.active as active1_, fundshare0_.CODE_BB as CODE4_1_, fundshare0_.deleted as deleted1_, fundshare0_.FUND_ID as FUND35_1_, fundshare0_.inception as inception1_, fundshare0_.INTERNAL_CODE as INTERNAL7_1_, fundshare0_.INTERNAL_SHARE as INTERNAL8_1_, fundshare0_.isin as isin1_, fundshare0_.ISO_CODE as ISO10_1_, fundshare0_.isprimary as isprimary1_, fundshare0_.LAST_PERF_AUDIT as LAST12_1_, fundshare0_.LIMIT_PERF_AUDIT as LIMIT13_1_, fundshare0_.LIQUIDITY_ID as LIQUIDITY14_1_, fundshare0_.MINIMUM_ADDITIONAL_INVEST as MINIMUM15_1_, fundshare0_.MINIMUM_INVESTMENT as MINIMUM16_1_, fundshare0_.NAV_MONITORING as NAV17_1_, fundshare0_.nominal as nominal1_, fundshare0_.OPEN_CLOSE_NAV as OPEN19_1_, fundshare0_.REFERENCE_SHARE as REFERENCE20_1_, fundshare0_.REPORTING_FREQUENCY_ID as REPORTING21_1_, fundshare0_.REPORTING_FREQUENCY_OTHER as REPORTING22_1_, fundshare0_.SERIE_ID as SERIE36_1_, fundshare0_.SHARE_CAPACITY as SHARE23_1_, fundshare0_.SHARE_CLASS as SHARE24_1_, fundshare0_.SHARE_NAME as SHARE25_1_, fundshare0_.SHARE_TYPE_ID as SHARE26_1_, fundshare0_.SHARE_TYPE_OTHER as SHARE27_1_, fundshare0_.SIDE_LETTER as SIDE28_1_, fundshare0_.STATS_START_DATE as STATS29_1_, fundshare0_.TRACK_START_DATE as TRACK30_1_, fundshare0_.updated as updated1_, fundshare0_.updater as updater1_, fundshare0_.whendeleted as whendel33_1_, fundshare0_.whodeleted as whodeleted1_ from FUND_SHARE fundshare0_
     * share list size = 21698
     * fund name = TOTO Fund
     *
     */
    public static void main(String[] args) {
        Session session = HibernateUtil.getSession();

        List lf = session.createQuery("from Fund").list();
        System.out.println("fund list size = " + lf.size());

        Long fundCount = (Long)session.createQuery("select count(fund) from Fund fund").uniqueResult();
        System.out.println("fund list size = " + fundCount);

        List ls = session.createQuery("from FundShare").list();
        System.out.println("share list size = " + ls.size());

        Fund fund = (Fund)session.get(Fund.class, new Long(1));
        System.out.println("fund name = " + fund.getFundName());
    }</pre>

Queries with JPA :

<pre>
    /**
     * JPA sample with queries
     *
     *    Output :
     *
     * Hibernate: select fund0_.FUND_ID as FUND1_1_, fund0_.ADMINISTRATOR_ID as ADMINIST2_1_, fund0_.ADVISORY_NAME as ADVISORY3_1_, fund0_.ANNUAL_AUDIT as ANNUAL4_1_, fund0_.AUDIT_FIRM as AUDIT5_1_, fund0_.auditor as auditor1_, fund0_.banker as banker1_, fund0_.CLASSIFICATION_ID as CLASSIFI8_1_, fund0_.codification as codifica9_1_, fund0_.COMM_STATUS as COMM10_1_, fund0_.COUNTRY_OF_DOMICILE_ID as COUNTRY11_1_, fund0_.DATA_VENDOR_FUND_ID as DATA12_1_, fund0_.DATA_VENDOR_ID as DATA13_1_, fund0_.deleted as deleted1_, fund0_.DISCLOSURE_ID as DISCLOSURE15_1_, fund0_.EXTCOM_AGREEMENT as EXTCOM16_1_, fund0_.FINANCIAL_AUTHORITY_ID1 as FINANCIAL17_1_, fund0_.FINANCIAL_AUTHORITY_ID2 as FINANCIAL18_1_, fund0_.FINANCIAL_AUTHORITY_ID3 as FINANCIAL19_1_, fund0_.FISCAL_YEAR_END as FISCAL20_1_, fund0_.FUND_CAPACITY as FUND21_1_, fund0_.FUND_DESCRIPTION as FUND22_1_, fund0_.FUND_NAME as FUND23_1_, fund0_.FUND_REDEMPTION_GATE_FUND_LVL as FUND24_1_, fund0_.FUND_REDEMPTION_GATE_IND_LVL as FUND25_1_, fund0_.GEOGRAPHICAL_FOCUS_ID as GEOGRAP26_1_, fund0_.inception as inception1_, fund0_.instruments as instrum28_1_, fund0_.internal as internal1_, fund0_.INVESTMENT_RESTRICTIONS as INVESTMENT30_1_, fund0_.INVESTMENT_STATUS_ID as INVESTMENT31_1_, fund0_.INVESTMENT_STRATEGY as INVESTMENT32_1_, fund0_.INVESTMENT_SUB_STATUS_ID as INVESTMENT33_1_, fund0_.ISO_CODE as ISO34_1_, fund0_.IVT_MANAGEMENT_FIRM_ID as IVT35_1_, fund0_.LAST_AUDIT as LAST36_1_, fund0_.LAST_DUE_DILIGENCE as LAST37_1_, fund0_.LEGAL_ADVISOR_ID1 as LEGAL38_1_, fund0_.LEGAL_ADVISOR_ID2 as LEGAL39_1_, fund0_.LEGAL_ADVISOR_ID3 as LEGAL40_1_, fund0_.LEGAL_ADVISOR_OFFSHORE as LEGAL41_1_, fund0_.LEGAL_COUNSEL as LEGAL42_1_, fund0_.LEGAL_DESCRIPTION as LEGAL43_1_, fund0_.LEGAL_DESCRIPTION_ID as LEGAL44_1_, fund0_.LISTED_ON_A_STOCK_EXCHANGE as LISTED45_1_, fund0_.MANAGED_ACCOUNT as MANAGED46_1_, fund0_.MANAGEMENT_FIRM_ID as MANAGEMENT47_1_, fund0_.MARKETING_NAME as MARKETING48_1_, fund0_.MASTER_FUND_ID as MASTER49_1_, fund0_.MASTER_FUND_NAME as MASTER50_1_, fund0_.OFFSHORE_NAME as OFFSHORE51_1_, fund0_.OFFSHORE_VEHICLE as OFFSHORE52_1_, fund0_.PLACEMENT_AGENT as PLACEMENT53_1_, fund0_.PRIMARY_SHARE as PRIMARY71_1_, fund0_.PTF_MANAGEMENT_FIRM_ID as PTF54_1_, fund0_.ranking as ranking1_, fund0_.REPORTING_FREQUENCY_ID as REPORTING56_1_, fund0_.REPORTING_FREQUENCY_OTHER as REPORTING57_1_, fund0_.RISK_POLICY as RISK58_1_, fund0_.SECTOR_FOCUS_ID as SECTOR59_1_, fund0_.SIDE_POCKET_ALLOWABLE as SIDE60_1_, fund0_.source as source1_, fund0_.SS_CLASSIFICATION_ID as SS62_1_, fund0_.SS_FOF_CLASSIFICATION_ID as SS63_1_, fund0_.SS_MS_CLASSIFICATION_ID as SS64_1_, fund0_.stage as stage1_, fund0_.status as status1_, fund0_.STATUS_ID as STATUS67_1_, fund0_.SUB_STRATEGY as SUB68_1_, fund0_.updated as updated1_, fund0_.updater as updater1_ from Fund fund0_
     * 1680
     * Hibernate: select * from ( select count(fund0_.FUND_ID) as col_0_0_ from Fund fund0_ ) where rownum <= ?
     * 1680
     * Hibernate: select fundview0_.FUND_ID as FUND1_2_, fundview0_.FUND_NAME as FUND2_2_ from TANIS.V_TNS_FUND fundview0_
     * FundView size = 1680
     * Hibernate: select * from ( select count(*) from FUND ) where rownum <= ?
     * 1680
     * Hibernate: select fund0_.FUND_ID as FUND1_1_, fund0_.ADMINISTRATOR_ID as ADMINIST2_1_, fund0_.ADVISORY_NAME as ADVISORY3_1_, fund0_.ANNUAL_AUDIT as ANNUAL4_1_, fund0_.AUDIT_FIRM as AUDIT5_1_, fund0_.auditor as auditor1_, fund0_.banker as banker1_, fund0_.CLASSIFICATION_ID as CLASSIFI8_1_, fund0_.codification as codifica9_1_, fund0_.COMM_STATUS as COMM10_1_, fund0_.COUNTRY_OF_DOMICILE_ID as COUNTRY11_1_, fund0_.DATA_VENDOR_FUND_ID as DATA12_1_, fund0_.DATA_VENDOR_ID as DATA13_1_, fund0_.deleted as deleted1_, fund0_.DISCLOSURE_ID as DISCLOSURE15_1_, fund0_.EXTCOM_AGREEMENT as EXTCOM16_1_, fund0_.FINANCIAL_AUTHORITY_ID1 as FINANCIAL17_1_, fund0_.FINANCIAL_AUTHORITY_ID2 as FINANCIAL18_1_, fund0_.FINANCIAL_AUTHORITY_ID3 as FINANCIAL19_1_, fund0_.FISCAL_YEAR_END as FISCAL20_1_, fund0_.FUND_CAPACITY as FUND21_1_, fund0_.FUND_DESCRIPTION as FUND22_1_, fund0_.FUND_NAME as FUND23_1_, fund0_.FUND_REDEMPTION_GATE_FUND_LVL as FUND24_1_, fund0_.FUND_REDEMPTION_GATE_IND_LVL as FUND25_1_, fund0_.GEOGRAPHICAL_FOCUS_ID as GEOGRAP26_1_, fund0_.inception as inception1_, fund0_.instruments as instrum28_1_, fund0_.internal as internal1_, fund0_.INVESTMENT_RESTRICTIONS as INVESTMENT30_1_, fund0_.INVESTMENT_STATUS_ID as INVESTMENT31_1_, fund0_.INVESTMENT_STRATEGY as INVESTMENT32_1_, fund0_.INVESTMENT_SUB_STATUS_ID as INVESTMENT33_1_, fund0_.ISO_CODE as ISO34_1_, fund0_.IVT_MANAGEMENT_FIRM_ID as IVT35_1_, fund0_.LAST_AUDIT as LAST36_1_, fund0_.LAST_DUE_DILIGENCE as LAST37_1_, fund0_.LEGAL_ADVISOR_ID1 as LEGAL38_1_, fund0_.LEGAL_ADVISOR_ID2 as LEGAL39_1_, fund0_.LEGAL_ADVISOR_ID3 as LEGAL40_1_, fund0_.LEGAL_ADVISOR_OFFSHORE as LEGAL41_1_, fund0_.LEGAL_COUNSEL as LEGAL42_1_, fund0_.LEGAL_DESCRIPTION as LEGAL43_1_, fund0_.LEGAL_DESCRIPTION_ID as LEGAL44_1_, fund0_.LISTED_ON_A_STOCK_EXCHANGE as LISTED45_1_, fund0_.MANAGED_ACCOUNT as MANAGED46_1_, fund0_.MANAGEMENT_FIRM_ID as MANAGEMENT47_1_, fund0_.MARKETING_NAME as MARKETING48_1_, fund0_.MASTER_FUND_ID as MASTER49_1_, fund0_.MASTER_FUND_NAME as MASTER50_1_, fund0_.OFFSHORE_NAME as OFFSHORE51_1_, fund0_.OFFSHORE_VEHICLE as OFFSHORE52_1_, fund0_.PLACEMENT_AGENT as PLACEMENT53_1_, fund0_.PRIMARY_SHARE as PRIMARY71_1_, fund0_.PTF_MANAGEMENT_FIRM_ID as PTF54_1_, fund0_.ranking as ranking1_, fund0_.REPORTING_FREQUENCY_ID as REPORTING56_1_, fund0_.REPORTING_FREQUENCY_OTHER as REPORTING57_1_, fund0_.RISK_POLICY as RISK58_1_, fund0_.SECTOR_FOCUS_ID as SECTOR59_1_, fund0_.SIDE_POCKET_ALLOWABLE as SIDE60_1_, fund0_.source as source1_, fund0_.SS_CLASSIFICATION_ID as SS62_1_, fund0_.SS_FOF_CLASSIFICATION_ID as SS63_1_, fund0_.SS_MS_CLASSIFICATION_ID as SS64_1_, fund0_.stage as stage1_, fund0_.status as status1_, fund0_.STATUS_ID as STATUS67_1_, fund0_.SUB_STRATEGY as SUB68_1_, fund0_.updated as updated1_, fund0_.updater as updater1_ from Fund fund0_ inner join FUND_SHARE fundsharec1_ on fund0_.FUND_ID=fundsharec1_.FUND_ID
     * 4396
     * Hibernate: select fund0_.FUND_ID as FUND1_1_, fund0_.ADMINISTRATOR_ID as ADMINIST2_1_, fund0_.ADVISORY_NAME as ADVISORY3_1_, fund0_.ANNUAL_AUDIT as ANNUAL4_1_, fund0_.AUDIT_FIRM as AUDIT5_1_, fund0_.auditor as auditor1_, fund0_.banker as banker1_, fund0_.CLASSIFICATION_ID as CLASSIFI8_1_, fund0_.codification as codifica9_1_, fund0_.COMM_STATUS as COMM10_1_, fund0_.COUNTRY_OF_DOMICILE_ID as COUNTRY11_1_, fund0_.DATA_VENDOR_FUND_ID as DATA12_1_, fund0_.DATA_VENDOR_ID as DATA13_1_, fund0_.deleted as deleted1_, fund0_.DISCLOSURE_ID as DISCLOSURE15_1_, fund0_.EXTCOM_AGREEMENT as EXTCOM16_1_, fund0_.FINANCIAL_AUTHORITY_ID1 as FINANCIAL17_1_, fund0_.FINANCIAL_AUTHORITY_ID2 as FINANCIAL18_1_, fund0_.FINANCIAL_AUTHORITY_ID3 as FINANCIAL19_1_, fund0_.FISCAL_YEAR_END as FISCAL20_1_, fund0_.FUND_CAPACITY as FUND21_1_, fund0_.FUND_DESCRIPTION as FUND22_1_, fund0_.FUND_NAME as FUND23_1_, fund0_.FUND_REDEMPTION_GATE_FUND_LVL as FUND24_1_, fund0_.FUND_REDEMPTION_GATE_IND_LVL as FUND25_1_, fund0_.GEOGRAPHICAL_FOCUS_ID as GEOGRAP26_1_, fund0_.inception as inception1_, fund0_.instruments as instrum28_1_, fund0_.internal as internal1_, fund0_.INVESTMENT_RESTRICTIONS as INVESTMENT30_1_, fund0_.INVESTMENT_STATUS_ID as INVESTMENT31_1_, fund0_.INVESTMENT_STRATEGY as INVESTMENT32_1_, fund0_.INVESTMENT_SUB_STATUS_ID as INVESTMENT33_1_, fund0_.ISO_CODE as ISO34_1_, fund0_.IVT_MANAGEMENT_FIRM_ID as IVT35_1_, fund0_.LAST_AUDIT as LAST36_1_, fund0_.LAST_DUE_DILIGENCE as LAST37_1_, fund0_.LEGAL_ADVISOR_ID1 as LEGAL38_1_, fund0_.LEGAL_ADVISOR_ID2 as LEGAL39_1_, fund0_.LEGAL_ADVISOR_ID3 as LEGAL40_1_, fund0_.LEGAL_ADVISOR_OFFSHORE as LEGAL41_1_, fund0_.LEGAL_COUNSEL as LEGAL42_1_, fund0_.LEGAL_DESCRIPTION as LEGAL43_1_, fund0_.LEGAL_DESCRIPTION_ID as LEGAL44_1_, fund0_.LISTED_ON_A_STOCK_EXCHANGE as LISTED45_1_, fund0_.MANAGED_ACCOUNT as MANAGED46_1_, fund0_.MANAGEMENT_FIRM_ID as MANAGEMENT47_1_, fund0_.MARKETING_NAME as MARKETING48_1_, fund0_.MASTER_FUND_ID as MASTER49_1_, fund0_.MASTER_FUND_NAME as MASTER50_1_, fund0_.OFFSHORE_NAME as OFFSHORE51_1_, fund0_.OFFSHORE_VEHICLE as OFFSHORE52_1_, fund0_.PLACEMENT_AGENT as PLACEMENT53_1_, fund0_.PRIMARY_SHARE as PRIMARY71_1_, fund0_.PTF_MANAGEMENT_FIRM_ID as PTF54_1_, fund0_.ranking as ranking1_, fund0_.REPORTING_FREQUENCY_ID as REPORTING56_1_, fund0_.REPORTING_FREQUENCY_OTHER as REPORTING57_1_, fund0_.RISK_POLICY as RISK58_1_, fund0_.SECTOR_FOCUS_ID as SECTOR59_1_, fund0_.SIDE_POCKET_ALLOWABLE as SIDE60_1_, fund0_.source as source1_, fund0_.SS_CLASSIFICATION_ID as SS62_1_, fund0_.SS_FOF_CLASSIFICATION_ID as SS63_1_, fund0_.SS_MS_CLASSIFICATION_ID as SS64_1_, fund0_.stage as stage1_, fund0_.status as status1_, fund0_.STATUS_ID as STATUS67_1_, fund0_.SUB_STRATEGY as SUB68_1_, fund0_.updated as updated1_, fund0_.updater as updater1_ from Fund fund0_ left outer join FUND_SHARE fundsharec1_ on fund0_.FUND_ID=fundsharec1_.FUND_ID
     * 4526
     */
    public static void main(String&#91;&#93; args) {
        EntityManagerFactory factory = Persistence.createEntityManagerFactory(null);
        EntityManager em = factory.createEntityManager();
        em.getTransaction().begin();

        try {
            //
            List funds = em.createQuery("from Fund").getResultList();
            System.out.println(funds.size());

            Object result = em.createQuery("select count(fund) from Fund fund").getSingleResult();
            System.out.println(result);

            List fundsView = em.createQuery("from FundView").getResultList();
            System.out.println("FundView size = " + fundsView.size());            

            Object o = em.createNativeQuery("select count(*) from FUND").getSingleResult();
            System.out.println(o);

            List fundsInnerJoin = em.createQuery("select fund from Fund as fund inner join fund.fundShareCollection as share").getResultList();
            System.out.println(fundsInnerJoin.size());

            List fundsOuterJoin = em.createQuery("select fund from Fund as fund left join fund.fundShareCollection as share").getResultList();
            System.out.println(fundsOuterJoin.size());

        } catch(Exception e) {
            e.printStackTrace();
        } finally {
            em.getTransaction().commit();
            em.close();
        }

&#91;/sourcecode&#93;

In memory query with JoSQL :

&#91;sourcecode language='java'&#93;
    /**
     * JPA example with a JoSQL query on in memory data retrived with JPA
     *
     * Output :
     *
     * Hibernate: select fund0_.FUND_ID as FUND1_1_, fund0_.ADMINISTRATOR_ID as ADMINIST2_1_, fund0_.ADVISORY_NAME as ADVISORY3_1_, fund0_.ANNUAL_AUDIT as ANNUAL4_1_, fund0_.AUDIT_FIRM as AUDIT5_1_, fund0_.auditor as auditor1_, fund0_.banker as banker1_, fund0_.CLASSIFICATION_ID as CLASSIFI8_1_, fund0_.codification as codifica9_1_, fund0_.COMM_STATUS as COMM10_1_, fund0_.COUNTRY_OF_DOMICILE_ID as COUNTRY11_1_, fund0_.DATA_VENDOR_FUND_ID as DATA12_1_, fund0_.DATA_VENDOR_ID as DATA13_1_, fund0_.deleted as deleted1_, fund0_.DISCLOSURE_ID as DISCLOSURE15_1_, fund0_.EXTCOM_AGREEMENT as EXTCOM16_1_, fund0_.FINANCIAL_AUTHORITY_ID1 as FINANCIAL17_1_, fund0_.FINANCIAL_AUTHORITY_ID2 as FINANCIAL18_1_, fund0_.FINANCIAL_AUTHORITY_ID3 as FINANCIAL19_1_, fund0_.FISCAL_YEAR_END as FISCAL20_1_, fund0_.FUND_CAPACITY as FUND21_1_, fund0_.FUND_DESCRIPTION as FUND22_1_, fund0_.FUND_NAME as FUND23_1_, fund0_.FUND_REDEMPTION_GATE_FUND_LVL as FUND24_1_, fund0_.FUND_REDEMPTION_GATE_IND_LVL as FUND25_1_, fund0_.GEOGRAPHICAL_FOCUS_ID as GEOGRAP26_1_, fund0_.inception as inception1_, fund0_.instruments as instrum28_1_, fund0_.internal as internal1_, fund0_.INVESTMENT_RESTRICTIONS as INVESTMENT30_1_, fund0_.INVESTMENT_STATUS_ID as INVESTMENT31_1_, fund0_.INVESTMENT_STRATEGY as INVESTMENT32_1_, fund0_.INVESTMENT_SUB_STATUS_ID as INVESTMENT33_1_, fund0_.ISO_CODE as ISO34_1_, fund0_.IVT_MANAGEMENT_FIRM_ID as IVT35_1_, fund0_.LAST_AUDIT as LAST36_1_, fund0_.LAST_DUE_DILIGENCE as LAST37_1_, fund0_.LEGAL_ADVISOR_ID1 as LEGAL38_1_, fund0_.LEGAL_ADVISOR_ID2 as LEGAL39_1_, fund0_.LEGAL_ADVISOR_ID3 as LEGAL40_1_, fund0_.LEGAL_ADVISOR_OFFSHORE as LEGAL41_1_, fund0_.LEGAL_COUNSEL as LEGAL42_1_, fund0_.LEGAL_DESCRIPTION as LEGAL43_1_, fund0_.LEGAL_DESCRIPTION_ID as LEGAL44_1_, fund0_.LISTED_ON_A_STOCK_EXCHANGE as LISTED45_1_, fund0_.MANAGED_ACCOUNT as MANAGED46_1_, fund0_.MANAGEMENT_FIRM_ID as MANAGEMENT47_1_, fund0_.MARKETING_NAME as MARKETING48_1_, fund0_.MASTER_FUND_ID as MASTER49_1_, fund0_.MASTER_FUND_NAME as MASTER50_1_, fund0_.OFFSHORE_NAME as OFFSHORE51_1_, fund0_.OFFSHORE_VEHICLE as OFFSHORE52_1_, fund0_.PLACEMENT_AGENT as PLACEMENT53_1_, fund0_.PRIMARY_SHARE as PRIMARY71_1_, fund0_.PTF_MANAGEMENT_FIRM_ID as PTF54_1_, fund0_.ranking as ranking1_, fund0_.REPORTING_FREQUENCY_ID as REPORTING56_1_, fund0_.REPORTING_FREQUENCY_OTHER as REPORTING57_1_, fund0_.RISK_POLICY as RISK58_1_, fund0_.SECTOR_FOCUS_ID as SECTOR59_1_, fund0_.SIDE_POCKET_ALLOWABLE as SIDE60_1_, fund0_.source as source1_, fund0_.SS_CLASSIFICATION_ID as SS62_1_, fund0_.SS_FOF_CLASSIFICATION_ID as SS63_1_, fund0_.SS_MS_CLASSIFICATION_ID as SS64_1_, fund0_.stage as stage1_, fund0_.status as status1_, fund0_.STATUS_ID as STATUS67_1_, fund0_.SUB_STRATEGY as SUB68_1_, fund0_.updated as updated1_, fund0_.updater as updater1_ from Fund fund0_
     * 1680
     * JoSQL query run total time = 15
     * JoSQL result count = 233
     * Hibernate: select fund0_.FUND_ID as FUND1_1_, fund0_.ADMINISTRATOR_ID as ADMINIST2_1_, fund0_.ADVISORY_NAME as ADVISORY3_1_, fund0_.ANNUAL_AUDIT as ANNUAL4_1_, fund0_.AUDIT_FIRM as AUDIT5_1_, fund0_.auditor as auditor1_, fund0_.banker as banker1_, fund0_.CLASSIFICATION_ID as CLASSIFI8_1_, fund0_.codification as codifica9_1_, fund0_.COMM_STATUS as COMM10_1_, fund0_.COUNTRY_OF_DOMICILE_ID as COUNTRY11_1_, fund0_.DATA_VENDOR_FUND_ID as DATA12_1_, fund0_.DATA_VENDOR_ID as DATA13_1_, fund0_.deleted as deleted1_, fund0_.DISCLOSURE_ID as DISCLOSURE15_1_, fund0_.EXTCOM_AGREEMENT as EXTCOM16_1_, fund0_.FINANCIAL_AUTHORITY_ID1 as FINANCIAL17_1_, fund0_.FINANCIAL_AUTHORITY_ID2 as FINANCIAL18_1_, fund0_.FINANCIAL_AUTHORITY_ID3 as FINANCIAL19_1_, fund0_.FISCAL_YEAR_END as FISCAL20_1_, fund0_.FUND_CAPACITY as FUND21_1_, fund0_.FUND_DESCRIPTION as FUND22_1_, fund0_.FUND_NAME as FUND23_1_, fund0_.FUND_REDEMPTION_GATE_FUND_LVL as FUND24_1_, fund0_.FUND_REDEMPTION_GATE_IND_LVL as FUND25_1_, fund0_.GEOGRAPHICAL_FOCUS_ID as GEOGRAP26_1_, fund0_.inception as inception1_, fund0_.instruments as instrum28_1_, fund0_.internal as internal1_, fund0_.INVESTMENT_RESTRICTIONS as INVESTMENT30_1_, fund0_.INVESTMENT_STATUS_ID as INVESTMENT31_1_, fund0_.INVESTMENT_STRATEGY as INVESTMENT32_1_, fund0_.INVESTMENT_SUB_STATUS_ID as INVESTMENT33_1_, fund0_.ISO_CODE as ISO34_1_, fund0_.IVT_MANAGEMENT_FIRM_ID as IVT35_1_, fund0_.LAST_AUDIT as LAST36_1_, fund0_.LAST_DUE_DILIGENCE as LAST37_1_, fund0_.LEGAL_ADVISOR_ID1 as LEGAL38_1_, fund0_.LEGAL_ADVISOR_ID2 as LEGAL39_1_, fund0_.LEGAL_ADVISOR_ID3 as LEGAL40_1_, fund0_.LEGAL_ADVISOR_OFFSHORE as LEGAL41_1_, fund0_.LEGAL_COUNSEL as LEGAL42_1_, fund0_.LEGAL_DESCRIPTION as LEGAL43_1_, fund0_.LEGAL_DESCRIPTION_ID as LEGAL44_1_, fund0_.LISTED_ON_A_STOCK_EXCHANGE as LISTED45_1_, fund0_.MANAGED_ACCOUNT as MANAGED46_1_, fund0_.MANAGEMENT_FIRM_ID as MANAGEMENT47_1_, fund0_.MARKETING_NAME as MARKETING48_1_, fund0_.MASTER_FUND_ID as MASTER49_1_, fund0_.MASTER_FUND_NAME as MASTER50_1_, fund0_.OFFSHORE_NAME as OFFSHORE51_1_, fund0_.OFFSHORE_VEHICLE as OFFSHORE52_1_, fund0_.PLACEMENT_AGENT as PLACEMENT53_1_, fund0_.PRIMARY_SHARE as PRIMARY71_1_, fund0_.PTF_MANAGEMENT_FIRM_ID as PTF54_1_, fund0_.ranking as ranking1_, fund0_.REPORTING_FREQUENCY_ID as REPORTING56_1_, fund0_.REPORTING_FREQUENCY_OTHER as REPORTING57_1_, fund0_.RISK_POLICY as RISK58_1_, fund0_.SECTOR_FOCUS_ID as SECTOR59_1_, fund0_.SIDE_POCKET_ALLOWABLE as SIDE60_1_, fund0_.source as source1_, fund0_.SS_CLASSIFICATION_ID as SS62_1_, fund0_.SS_FOF_CLASSIFICATION_ID as SS63_1_, fund0_.SS_MS_CLASSIFICATION_ID as SS64_1_, fund0_.stage as stage1_, fund0_.status as status1_, fund0_.STATUS_ID as STATUS67_1_, fund0_.SUB_STRATEGY as SUB68_1_, fund0_.updated as updated1_, fund0_.updater as updater1_ from Fund fund0_ where fund0_.FUND_NAME like '%SGAM%'
     * JPA query run total time = 609
     * JPA result count = 233
     */
    public static void main(String&#91;&#93; args) {
        EntityManagerFactory factory = Persistence.createEntityManagerFactory(null);
        EntityManager em = factory.createEntityManager();
        em.getTransaction().begin();

        try {
            Query query = em.createQuery("from Fund");
            List funds = query.getResultList();
            System.out.println(funds.size());

            // prepare and run the JoSQL Query :
            org.josql.Query josqlQuery = new org.josql.Query();
            josqlQuery.parse("select * from models.generated.Fund where fundName like '%SGAM%'");
            long start = System.currentTimeMillis();
            QueryResults qr = josqlQuery.execute(funds);
            List<Fund> fundsResult = qr.getResults();
            System.out.println("JoSQL query run total time = " + (System.currentTimeMillis() - start));
            System.out.println( "JoSQL result count = " + fundsResult.size() );

            // query to check that the result size found with JoSQL is ok :
            Query query2 = em.createQuery("select fund from Fund fund where fund.fundName like '%SGAM%'");
            start = System.currentTimeMillis();
            List count = query2.getResultList();
            System.out.println("JPA query run total time = " + (System.currentTimeMillis() - start));
            System.out.println("JPA result count = " + count.size());            

            // Display result
            int i=0;
            for (Fund f:fundsResult)
                System.out.println(i++ + " = " + f.getFundName());

        } catch(Exception e) {
            e.printStackTrace();
        } finally {
            em.getTransaction().commit();
            em.close();
        }

    }

In memory query with Lucene :

<pre>    /**
     * Simple example with Lucene indexing and querying
     *
     * Output :
     *
     * Hibernate: select fund0_.FUND_ID as FUND1_1_, fund0_.ADMINISTRATOR_ID as ADMINIST2_1_, fund0_.ADVISORY_NAME as ADVISORY3_1_, fund0_.ANNUAL_AUDIT as ANNUAL4_1_, fund0_.AUDIT_FIRM as AUDIT5_1_, fund0_.auditor as auditor1_, fund0_.banker as banker1_, fund0_.CLASSIFICATION_ID as CLASSIFI8_1_, fund0_.codification as codifica9_1_, fund0_.COMM_STATUS as COMM10_1_, fund0_.COUNTRY_OF_DOMICILE_ID as COUNTRY11_1_, fund0_.DATA_VENDOR_FUND_ID as DATA12_1_, fund0_.DATA_VENDOR_ID as DATA13_1_, fund0_.deleted as deleted1_, fund0_.DISCLOSURE_ID as DISCLOSURE15_1_, fund0_.EXTCOM_AGREEMENT as EXTCOM16_1_, fund0_.FINANCIAL_AUTHORITY_ID1 as FINANCIAL17_1_, fund0_.FINANCIAL_AUTHORITY_ID2 as FINANCIAL18_1_, fund0_.FINANCIAL_AUTHORITY_ID3 as FINANCIAL19_1_, fund0_.FISCAL_YEAR_END as FISCAL20_1_, fund0_.FUND_CAPACITY as FUND21_1_, fund0_.FUND_DESCRIPTION as FUND22_1_, fund0_.FUND_NAME as FUND23_1_, fund0_.FUND_REDEMPTION_GATE_FUND_LVL as FUND24_1_, fund0_.FUND_REDEMPTION_GATE_IND_LVL as FUND25_1_, fund0_.GEOGRAPHICAL_FOCUS_ID as GEOGRAP26_1_, fund0_.inception as inception1_, fund0_.instruments as instrum28_1_, fund0_.internal as internal1_, fund0_.INVESTMENT_RESTRICTIONS as INVESTMENT30_1_, fund0_.INVESTMENT_STATUS_ID as INVESTMENT31_1_, fund0_.INVESTMENT_STRATEGY as INVESTMENT32_1_, fund0_.INVESTMENT_SUB_STATUS_ID as INVESTMENT33_1_, fund0_.ISO_CODE as ISO34_1_, fund0_.IVT_MANAGEMENT_FIRM_ID as IVT35_1_, fund0_.LAST_AUDIT as LAST36_1_, fund0_.LAST_DUE_DILIGENCE as LAST37_1_, fund0_.LEGAL_ADVISOR_ID1 as LEGAL38_1_, fund0_.LEGAL_ADVISOR_ID2 as LEGAL39_1_, fund0_.LEGAL_ADVISOR_ID3 as LEGAL40_1_, fund0_.LEGAL_ADVISOR_OFFSHORE as LEGAL41_1_, fund0_.LEGAL_COUNSEL as LEGAL42_1_, fund0_.LEGAL_DESCRIPTION as LEGAL43_1_, fund0_.LEGAL_DESCRIPTION_ID as LEGAL44_1_, fund0_.LISTED_ON_A_STOCK_EXCHANGE as LISTED45_1_, fund0_.MANAGED_ACCOUNT as MANAGED46_1_, fund0_.MANAGEMENT_FIRM_ID as MANAGEMENT47_1_, fund0_.MARKETING_NAME as MARKETING48_1_, fund0_.MASTER_FUND_ID as MASTER49_1_, fund0_.MASTER_FUND_NAME as MASTER50_1_, fund0_.OFFSHORE_NAME as OFFSHORE51_1_, fund0_.OFFSHORE_VEHICLE as OFFSHORE52_1_, fund0_.PLACEMENT_AGENT as PLACEMENT53_1_, fund0_.PRIMARY_SHARE as PRIMARY71_1_, fund0_.PTF_MANAGEMENT_FIRM_ID as PTF54_1_, fund0_.ranking as ranking1_, fund0_.REPORTING_FREQUENCY_ID as REPORTING56_1_, fund0_.REPORTING_FREQUENCY_OTHER as REPORTING57_1_, fund0_.RISK_POLICY as RISK58_1_, fund0_.SECTOR_FOCUS_ID as SECTOR59_1_, fund0_.SIDE_POCKET_ALLOWABLE as SIDE60_1_, fund0_.source as source1_, fund0_.SS_CLASSIFICATION_ID as SS62_1_, fund0_.SS_FOF_CLASSIFICATION_ID as SS63_1_, fund0_.SS_MS_CLASSIFICATION_ID as SS64_1_, fund0_.stage as stage1_, fund0_.status as status1_, fund0_.STATUS_ID as STATUS67_1_, fund0_.SUB_STRATEGY as SUB68_1_, fund0_.updated as updated1_, fund0_.updater as updater1_ from Fund fund0_
     * Collection size = 1680
     * Hibernate: select this_.FUND_ID as FUND1_1_0_, this_.ADMINISTRATOR_ID as ADMINIST2_1_0_, this_.ADVISORY_NAME as ADVISORY3_1_0_, this_.ANNUAL_AUDIT as ANNUAL4_1_0_, this_.AUDIT_FIRM as AUDIT5_1_0_, this_.auditor as auditor1_0_, this_.banker as banker1_0_, this_.CLASSIFICATION_ID as CLASSIFI8_1_0_, this_.codification as codifica9_1_0_, this_.COMM_STATUS as COMM10_1_0_, this_.COUNTRY_OF_DOMICILE_ID as COUNTRY11_1_0_, this_.DATA_VENDOR_FUND_ID as DATA12_1_0_, this_.DATA_VENDOR_ID as DATA13_1_0_, this_.deleted as deleted1_0_, this_.DISCLOSURE_ID as DISCLOSURE15_1_0_, this_.EXTCOM_AGREEMENT as EXTCOM16_1_0_, this_.FINANCIAL_AUTHORITY_ID1 as FINANCIAL17_1_0_, this_.FINANCIAL_AUTHORITY_ID2 as FINANCIAL18_1_0_, this_.FINANCIAL_AUTHORITY_ID3 as FINANCIAL19_1_0_, this_.FISCAL_YEAR_END as FISCAL20_1_0_, this_.FUND_CAPACITY as FUND21_1_0_, this_.FUND_DESCRIPTION as FUND22_1_0_, this_.FUND_NAME as FUND23_1_0_, this_.FUND_REDEMPTION_GATE_FUND_LVL as FUND24_1_0_, this_.FUND_REDEMPTION_GATE_IND_LVL as FUND25_1_0_, this_.GEOGRAPHICAL_FOCUS_ID as GEOGRAP26_1_0_, this_.inception as inception1_0_, this_.instruments as instrum28_1_0_, this_.internal as internal1_0_, this_.INVESTMENT_RESTRICTIONS as INVESTMENT30_1_0_, this_.INVESTMENT_STATUS_ID as INVESTMENT31_1_0_, this_.INVESTMENT_STRATEGY as INVESTMENT32_1_0_, this_.INVESTMENT_SUB_STATUS_ID as INVESTMENT33_1_0_, this_.ISO_CODE as ISO34_1_0_, this_.IVT_MANAGEMENT_FIRM_ID as IVT35_1_0_, this_.LAST_AUDIT as LAST36_1_0_, this_.LAST_DUE_DILIGENCE as LAST37_1_0_, this_.LEGAL_ADVISOR_ID1 as LEGAL38_1_0_, this_.LEGAL_ADVISOR_ID2 as LEGAL39_1_0_, this_.LEGAL_ADVISOR_ID3 as LEGAL40_1_0_, this_.LEGAL_ADVISOR_OFFSHORE as LEGAL41_1_0_, this_.LEGAL_COUNSEL as LEGAL42_1_0_, this_.LEGAL_DESCRIPTION as LEGAL43_1_0_, this_.LEGAL_DESCRIPTION_ID as LEGAL44_1_0_, this_.LISTED_ON_A_STOCK_EXCHANGE as LISTED45_1_0_, this_.MANAGED_ACCOUNT as MANAGED46_1_0_, this_.MANAGEMENT_FIRM_ID as MANAGEMENT47_1_0_, this_.MARKETING_NAME as MARKETING48_1_0_, this_.MASTER_FUND_ID as MASTER49_1_0_, this_.MASTER_FUND_NAME as MASTER50_1_0_, this_.OFFSHORE_NAME as OFFSHORE51_1_0_, this_.OFFSHORE_VEHICLE as OFFSHORE52_1_0_, this_.PLACEMENT_AGENT as PLACEMENT53_1_0_, this_.PRIMARY_SHARE as PRIMARY71_1_0_, this_.PTF_MANAGEMENT_FIRM_ID as PTF54_1_0_, this_.ranking as ranking1_0_, this_.REPORTING_FREQUENCY_ID as REPORTING56_1_0_, this_.REPORTING_FREQUENCY_OTHER as REPORTING57_1_0_, this_.RISK_POLICY as RISK58_1_0_, this_.SECTOR_FOCUS_ID as SECTOR59_1_0_, this_.SIDE_POCKET_ALLOWABLE as SIDE60_1_0_, this_.source as source1_0_, this_.SS_CLASSIFICATION_ID as SS62_1_0_, this_.SS_FOF_CLASSIFICATION_ID as SS63_1_0_, this_.SS_MS_CLASSIFICATION_ID as SS64_1_0_, this_.stage as stage1_0_, this_.status as status1_0_, this_.STATUS_ID as STATUS67_1_0_, this_.SUB_STRATEGY as SUB68_1_0_, this_.updated as updated1_0_, this_.updater as updater1_0_ from Fund this_ where (this_.FUND_ID in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?))
     * Lucene query time = 703
     * Lucene query result size = 234
     *
     */
    public static void main(String[] args) {
        EntityManagerFactory factory = Persistence.createEntityManagerFactory(null);

        EntityManager em = factory.createEntityManager();

        em.getTransaction().begin();

        try {
            // Get all the data
            List<Fund> funds = em.createQuery("from Fund").getResultList();
            System.out.println("Collection size = " + funds.size());

            // index fields for each fund (in our case we are just indexing the fundName field)
            FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(em);
            for(Fund fund : funds)
                fullTextEntityManager.index(fund);

            // Create a Lucene request to get all the funds with SGAM in its name
            MultiFieldQueryParser parser = new MultiFieldQueryParser(new String[]{"fundName"}, new StandardAnalyzer());
            org.apache.lucene.search.Query luceneQuery = parser.parse("SGAM");
            FullTextQuery query = fullTextEntityManager.createFullTextQuery(luceneQuery, Fund.class);

            long start = System.currentTimeMillis();
            List<Fund> list = query.getResultList();
            System.out.println("Lucene query time = " + (System.currentTimeMillis() - start));
            System.out.println("Lucene query result size = " + list.size());

            // Display result
            int i=0;
            for (Fund f:list) {
                System.out.println(i++ + " = " + f.getFundName());
            }

        } catch(Exception e) {
            e.printStackTrace();
        } finally {
            em.getTransaction().commit();
            em.close();
        }

    }
Categories: java Tags: , , , ,

Synchronizing threads

December 10, 2008 Leave a comment

To synchronize thread, use the monitoring methods.

Warning : the monitoring methods are available on all the java classes in any conditions albeit calling these method outside synchronied code will throw an exception. The following example describes it :

public static void main(String[] args) throws InterruptedException {
  Object lock = new Object();

  synchronized (lock) {
    System.out.println("calling a monitor method inside a synchronized block");
    lock.wait(1000);
  }

  System.out.println("calling a monitor method outside a synchronized block");
  lock.wait(1000);
}

This will lead to the following output :

calling a monitor method inside a synchronized block
calling a monitor method outside a synchronized block
Exception in thread “main” java.lang.IllegalMonitorStateException: current thread not owner
at java.lang.Object.wait(Native Method)
at TestThreadMonitor.main(TestThreadMonitor.java:15)

Categories: Uncategorized Tags: ,

Thread basics

December 10, 2008 Leave a comment

First of all the thread life cycle :

Thread Life Cycle

Thread Life Cycle

(Source reference: http://www.witscale.com/scjp_studynotes/chapter8.html)

There is two wayq to create a thread an run it :

Directly by extending the Thread class:

public class MyThread extends Thread {
  @Override
  public void run() {
  // do some stuff here
  }
}

To call it somewhere in you java code :

new MyThread().start();

Or by implementing the Runnable interface:

public class MyRunnable implements Runnable {
  Public void run() {
  // do some stuff here
  }
}

To call it somewhere in you java code :

new Thread(new MyRunnable()).start();

The best practice is to use the Runnable interface, this allows you to extends a business class or other if needed and its offers a better separation (than being stuck with the Thread class).

Categories: Uncategorized Tags: ,

Retreiving annotation data using introspection and dynamic proxy

December 10, 2008 Leave a comment

Just trying a simple test to retreive the annotation data during runtime using introspection.

Here’s the classes created for the test:

annotationsandproxy

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
    String value();
}

public class MyProxy implements InvocationHandler {

    private Object impl;

    private MyProxy(Object impl) {
        this.impl = impl;
    }

    public static Object newInstance(Object impl, Class[] interfaces) {
        return Proxy.newProxyInstance(impl.getClass().getClassLoader(), interfaces, new MyProxy(impl));
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // get the implementation object method on which the annotation has been setted
        Method implObjectMethod = impl.getClass().getMethod(method.getName(), method.getParameterTypes());

        // print the annotation in output
        Annotation[] annotations = implObjectMethod.getAnnotations();
        for (int i=0;i

Beans Binding (JSR 295) with POJO and AOP

December 2, 2008 11 comments

(download the net beans project : BeansBindingTest.zip.ppt : rename to .zip before opening)

Beans binding (JSR 295) is about keeping two properties in sync. To take a Simple example, let say that you have a simple text field (the view) in a Swing form and that you want it to be kept in sync with a POJO (the data model).

In a small first part I show how this can be done the standard way and in a second part how we can enhanced it we some simple AOP.

Part 1 : the standard way

Here the simple user form that we will create and bind with our data model :

beansbindingjrs295

And here the PersonVO.java POJO to be used as data model :


public class PersonVO {

  private String name;
  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }
}

public class PersonVOBindingEnabled extends PersonVO {
  protected PropertyChangeSupport props = new PropertyChangeSupport(this);
  public void addPropertyChangeListener( PropertyChangeListener l) {
    System.out.println("addPropertyChangeListener");
    props.addPropertyChangeListener(l);
  }

  public void removePropertyChangeListener( PropertyChangeListener l) {
    System.out.println("removePropertyChangeListener");
    props.removePropertyChangeListener(l);
  }

  public void setName(String newName) {
    String oldValue = getName();
    super.setName();
    props.firePropertyChange("name", oldName, newName);
  }
}

To bind the name attribute with the JTextField we use the Beans binding API :

JTextField nameTextField =…

PersonVO aPersonVO = new PersonVO();

aPersonVO.setName(“Brian”);

…

BeanProperty nameProperty = BeanProperty.create("name");

Binding b = Bindings.createAutoBinding(UpdateStrategy.READ_WRITE, aPersonVO, nameProperty, nameTextField, BeanProperty.create("text"));

And that’s it !

If you change the name attribute on the aPersonVO instance it will be sync in the JTextField and vice versa.

Yes but …

Having to extend the PersonVO so that it gets the PropertyChangeSupport is really annoying so it could be great if we could find a way to avoid it.

Part 2 : Using AOP

I have used AspectJ to automatically find my VO objects and add them all the necessary stuff for us :

package beansbindingtest.aspects;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import org.apache.commons.beanutils.PropertyUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.DeclareParents;

public @Aspect class PropertyChangeListenerAspect {
  public interface ChangeListener {

  public void addPropertyChangeListener( PropertyChangeListener l);
  public void removePropertyChangeListener( PropertyChangeListener l);
  public String getPropertyName(String setterMethodName);
  public PropertyChangeSupport getPropertyChangeSupport();
}

public static class ChangeListenerImpl implements ChangeListener {

  protected PropertyChangeSupport props = new PropertyChangeSupport(this);

  public void addPropertyChangeListener( PropertyChangeListener l) {
    System.out.println("addPropertyChangeListener");
    props.addPropertyChangeListener(l);
  }

  public void removePropertyChangeListener( PropertyChangeListener l) {
    System.out.println("removePropertyChangeListener");
    props.removePropertyChangeListener(l);
  }

  public String getPropertyName(String setterMethodName) {
    setterMethodName = setterMethodName.substring(3);
    String firstLetter = setterMethodName.substring(0, 1);
    setterMethodName = firstLetter.toLowerCase() + setterMethodName.substring(1);
    return setterMethodName;
  }

  public PropertyChangeSupport getPropertyChangeSupport() {
    return props;
  }
}

  @DeclareParents(value="beansbindingtest.datamodel.*",defaultImpl=ChangeListenerImpl.class)
  private ChangeListener implInterface;

  @Around("execution(void *..*VO.set*(..))")
  public void interceptSetterAndFirePropertyChange(ProceedingJoinPoint pjp) throws Throwable {
    System.out.println("before " + pjp.getSignature().getName());
    String setterMethodName = pjp.getSignature().getName().substring(3);
    String firstLetter = setterMethodName.substring(0, 1);
    String propertyName = firstLetter.toLowerCase() + setterMethodName.substring(1);
    Object oldValue = null;
    try {
      oldValue = PropertyUtils.getProperty(pjp.getTarget(), propertyName);
    } catch (Exception e) {
      e.printStackTrace();
    }
    Object newValue = pjp.getArgs()[0];

    pjp.proceed();

    System.out.println("Firing event : " + propertyName + "; oldValue = " + oldValue + "; newValue = " + newValue);
    PropertyChangeEvent pe = new PropertyChangeEvent(pjp.getTarget(), propertyName, oldValue, newValue);
    ((ChangeListener)pjp.getTarget()).getPropertyChangeSupport().firePropertyChange(pe);
    System.out.println("after " + pjp.getSignature().getName());
  }

}

I have used the following jars :

  • aspectjrt-1.5.4.jar
  • aspectjweaver-1.5.4.jar
  • commons-beanutils-1.8.0.jar
  • commons-logging-1.1.1.jar

aop.xml has to be copied in the META-INF directory of your source.

And you need to add these args to the JVM when starting the application :

-javaagent:[set your path here]/aspectjweaver-1.5.4.jar

What is your opinion about using AOP for bean binding ?

Categories: java Tags: , , ,