facebook

Changes in JPA ReverseEngineering from MyEclipse 6 to 7

  1. MyEclipse Archived
  2.  > 
  3. Database Tools (DB Explorer, Hibernate, etc.)
Viewing 6 posts - 1 through 6 (of 6 total)
  • Author
    Posts
  • #296090 Reply

    Hello,

    Previously MyEclipse 6 when it encounters a Number Column(Oracle) the generated entity used to map to Long by default. Now it maps to big decimal by default.Is there any specific reason for this change?

    #296148 Reply

    Brian Fernandes
    Moderator

    tokrishnakumar,

    The NUMBER type in Oracle can contain floating point values (if you supply a precision component), this is why BigDecimal is more appropriate than Long.

    If you wish to go back to Long, on page 3 of the RE wizard, select the column and in the Hibernate type field, type in “java.lang.Long”.

    Hope this helps.

    #296540 Reply

    Mark Henning
    Member

    @Support-Brian wrote:

    tokrishnakumar,

    The NUMBER type in Oracle can contain floating point values (if you supply a precision component), this is why BigDecimal is more appropriate than Long.

    If you wish to go back to Long, on page 3 of the RE wizard, select the column and in the Hibernate type field, type in “java.lang.Long”.

    Hope this helps.

    Brian,

    The problem is a bit more complicated than it appears. Consider the following simple scenario:

    CREATE TABLE BAZ.BAR (
    bar_id NUMBER(20),
    value NUMBER(22,9));

    CREATE SEQUENCE BAR_SEQ START WITH 1 INCREMENT BY 1;

    CREATE TABLE BAZ.FOO (
    foo_id NUMBER(20) PRIMARY KEY,
    bar_ref_id NUMBER(20) REFERENCES BAR(bar_id),
    foo_name VARCHAR2(50),
    foo_value NUMBER(22,9));

    CREATE SEQUENCE FOO_SEQ START WITH 1 INCREMENT BY 1;

    If you select default behavior, you will get


    @Entity

    @SequenceGenerator(name = “foo_sequence”, sequenceName =”BAZ.FOO_SEQ”) // added by hand
    @Table(name=”FOO”, schema=”BAZ”)
    public class foo

    private BigDecimal foo_id;
    private BigDecimal bar_ref_id;
    private String foo_name;
    private BigDecimal foo_value;

    This works fine until you try to annotate the foo_id with
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator=”foo_sequence”)
    This gets an error that the sequence generator can only do long, int, short types.

    If you change the mapping to Long, there is the reverse problem: foo_value would be a long. This is incorrect as well, as it actually represents a floating point number.

    The appropriate mappings for oracle would be:
    NUMBER ==> BigDecimal
    NUMBER(p) ==> Long
    NUMBER(p,s) ==> BigDecimal

    Can that be accomplished with the current jpa.reveng.xml specification?
    if not, can it be accomplished by implementing an extension of DelegatingReverseEngineeringStrategy?

    #296553 Reply

    Brian Fernandes
    Moderator

    tokrishnakumar,
    Thanks for the detailed report. Yes, you can fix this with the current reverse engineering settings. As I mentioned above, on page 3 of the RE wizard, expand your table and specify java.lang.Long for the foo_id column. This is not a general mapping that would convert all BigDecimal types to Long, it is specific to this column only. If you don’t touch the foo_value column, it will continue to be of type BigDecimal.

    I hope that helps, please let me know if I have misunderstood.

    #296555 Reply

    Mark Henning
    Member

    @Support-Brian wrote:

    tokrishnakumar,
    Thanks for the detailed report. Yes, you can fix this with the current reverse engineering settings. As I mentioned above, on page 3 of the RE wizard, expand your table and specify java.lang.Long for the foo_id column. This is not a general mapping that would convert all BigDecimal types to Long, it is specific to this column only. If you don

    Brian,

    Thank you for the quick reply.

    I see where you are going… Page 3 of the wizard is a “manual” step, which is fine for a few tables. The only problem is that what I’m working with is a government-change-managed data model which currently has 608 entities; for which there are a total 1415 foreign key constraints. fortunately I am only working with a number of subsets of tables varying from 3 to 60 tables in each set. Nevertheless, this makes for a fairly large number of custom mappings where I could accidentally introduce human error to what should be an otherwise relativly robust process. This data model is on a roughly 6 month change cycle, which means that whatever I do should be repeatable to handle rebuilding the entities in use if changes have been made.

    I have tried the following configuration, but the EJB3 reverse engineer process is still generating questionable mappings. The Table description and mapping result follows the xml configuration. Please note that it decided that access_role_id should be long, but login_id should be BigDecimal, even though they are the same type. The difference between the two is that the correctly mapped column is NOT part of the primary key. It appears that my configuration is not being checked for primary key fields. Is there a jdbc-type other than type NUMERIC that I should be looking for? I also tried scale=”0″ instead of precision=”20″ with identical results.

    Mark D Henning
    Principal Software Engineer
    ITT Corporation, Advanced Engineering and Sciences
    763-463-0057
    mark.henning@itt.com

    <?xml version=”1.0″ encoding=”UTF-8″?>
    <!DOCTYPE hibernate-reverse-engineering PUBLIC “-//Hibernate/Hibernate Reverse Engineering DTD 3.0//EN” “http://hibernate.sourceforge.net/hibernate-reverse-engineering-3.0.dtd&#8221; >

    <hibernate-reverse-engineering>
    <type-mapping>
    <sql-type jdbc-type=”TIMESTAMP” hibernate-type=”java.util.Date”></sql-type>
    <sql-type jdbc-type=”NUMERIC” precision=”20″ hibernate-type=”java.lang.Long”></sql-type>
    <sql-type jdbc-type=”NUMERIC” hibernate-type=”java.math.BigDouble”></sql-type>
    </type-mapping>
    </hibernate-reverse-engineering>

    SQL> desc login
    Name Null? Type
    —————————————– ——– —————————-
    LOGIN_ID NOT NULL NUMBER(20)
    ACCESS_ROLE_ID NOT NULL NUMBER(20)
    LOGIN_NAME_TXT VARCHAR2(32)
    LOGIN_PWD_TXT VARCHAR2(32)
    LAST_PWD_CHNG_DTTM DATE
    PWD_NON_REUSE_CNT NUMBER(2)

    /**
    * LoginId entity. @author MyEclipse Persistence Tools
    */
    @Embeddable
    public class LoginId implements java.io.Serializable {

    // Fields

    private BigDecimal loginId;
    private Long accessRoleId;
    ……
    @Column(name = “LOGIN_ID”, nullable = false, precision = 20, scale = 0)
    public BigDecimal getLoginId() {
    return this.loginId;
    }
    ………
    @Column(name = “ACCESS_ROLE_ID”, nullable = false, precision = 20, scale = 0)
    public Long getAccessRoleId() {
    return this.accessRoleId;
    }

    #296909 Reply

    Brian Fernandes
    Moderator

    Sorry for the delayed response, I missed the reply notification email.

    I do understand that making a manual mapping for so many columns could be error prone. You should be able to fix this by specifying your own reverse engineering strategy and overriding the columnToHibernateTypeName method. Detailed instructions on overriding the reverse engineering strategy are present in our Hibernate tutorial. I hope this helps, please let us know if you need further assistance.

Viewing 6 posts - 1 through 6 (of 6 total)
Reply To: Changes in JPA ReverseEngineering from MyEclipse 6 to 7

You must be logged in to post in the forum log in