Составной первичный ключ Не обновляется корректно с помощью EclipseLink.Где, как и в спящем режиме, это так.Зачем? - PullRequest
0 голосов
/ 02 апреля 2011

Я разместил весь код и проблему с выбором здесь .

Теперь я собираюсь задать еще одну проблему, которую я видел с eclipselink, которую я не видел с hibernate.

Теперь, когда мне удалось запустить загрузку, я попробовал сохранить профиль и выполнить каскадную операцию сохранения для связанных дочерних сущностей ProfileItem.

С помощью Hibernate я так закодировал код, который работал отличноfine:

//Parent class
@Entity
@Table(name="profile_table")
public class XVMUpdateProfile implements Serializable {


    @Id
    @Column(name="profile_id")
    @TableGenerator(name = "UCERELAY_TABLE_GENERATOR",
                    table= "SEQUENCE",
                    pkColumnName="SEQ_NAME",
                    valueColumnName ="SEQ_COUNT",
                    pkColumnValue="PROFILE_SEQ",
                    initialValue = 30,
                    allocationSize = 10)
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "UCERELAY_TABLE_GENERATOR")
    private Integer profileId ;

    ...

    /**
     *  WORKS WITH HIBERNATE AS PERSISTENCE PROVIDER
    */
    @OneToMany( cascade = CascadeType.ALL )
    @JoinColumn( name= "profile_id", referencedColumnName="profile_id" )
    private Set<XVMUpdateProfileItem> profileItems = null;

   ...
}

Теперь давайте увидим его дочерний элемент и его класс @EmbeddedId PK:

@Entity
@Table(name="profile_basket_table")
public class XVMUpdateProfileItem implements Serializable, Comparable<XVMUpdateProfileItem> {

    private static Log logger = LogFactory.getLog(XVMUpdateProfileItem.class);
    private static final long serialVersionUID = 1L;

    @EmbeddedId
    private XVMUpdateProfileItemPK key;

    ...
}

@Embeddable
public class XVMUpdateProfileItemPK implements Serializable, Comparable<XVMUpdateProfileItemPK>  {

    private static final long serialVersionUID = 1L;

    @Column(name="profile_id", nullable=false)
    private int keyId = 1;  // assigned a default value.

    @Column(name="from_node", nullable=false)
    private int fromNode = -2;

}

Моя основная программа:

public class UpdateProfileSave3 {

    private static Log logger = LogFactory.getLog(UpdateProfileMain.class);
    private static EntityManagerFactory emf = Persistence.createEntityManagerFactory("usinghibernate");
     public static void main(String args[]) {
        List<XVMUpdateProfile> profiles = new ArrayList<XVMUpdateProfile>();
        try {
            // First unit of work
            EntityManager em = emf.createEntityManager();

               EntityTransaction etx = em.getTransaction();
            etx.begin();

            XVMUpdateProfile profile = new XVMUpdateProfile();
            profile.setCreatorId(90);
            profile.setProfileDescription("Newly created to check generation of id");
            profile.setProfileName("Mahesh Babu Profile");

            Set<XVMUpdateProfileItem> items = profile.getProfileItems();

            XVMUpdateProfileItem newItem = new XVMUpdateProfileItem();
            newItem.setAction(XVMUpdateAction.ITEM_INSTALL);
            newItem.getKey().setFromNode(90);

            items.add(newItem);
            profile.setProfileItems(items);
            em.persist(profile);
            etx.commit();
            em.close();
        }catch(Exception ex){
            logger.debug(" Arun Could not load profiles : " + ex.getMessage());
            ex.printStackTrace();
        }           
}

Я создал одну родительскую сущность(профиль) и прикрепил одну дочернюю сущность (profile_item) и сохранил родительскую сущность (профиль).Я ожидал, что он вставит один профиль и один profile_item с правильным profile_id.

Как и ожидалось, он сделал это с 3 операторами DML:

insert into profile_table (creator_manager_id, lastupdate, description, profile_name, creatorname, profile_id) values (90, '2011-04-01 15:23:48', 'Newly created to check generation of id', 'Mahesh Babu Profile', 'Unspecified', 1130);

insert into profile_basket_table (action, from_node, profile_id) values (9, 90, 1)

update profile_basket_table set profile_id=1130 where from_node=90 and profile_id=1

DB results :

select PROFILE_ID, CREATOR_MANAGER_ID from profile_table where profile_id = 1130;

PROFILE_ID     CREATOR_MANAGER_ID    
---------------------- ----------------------
1130                   90                    


select * from profile_basket_table where profile_id = 1130;

FROM_NODE  PROFILE_ID     ACTION                
---------------------- ---------------------- ----------------------
90                     1130                   4                     

Вставил родительский и дочерний элементы, как и ожидалось.С hibernate все работало идеально.

Позволяет сменить поставщика сохраняемости на eclipselink.Давайте теперь используем eclipselink и увидим ту же проблему.Теперь со ссылкой на затмение, после исправления проблемы, упомянутой в Проблема 1 ,

Я попытался выполнить ту же проблему, с исправлением в одну строку:

   private static EntityManagerFactory emf = Persistence.createEntityManagerFactory("usingeclipselink");

Он также издает 3 заявления.Но последнее заявление об обновлении было ошибочным.

INSERT INTO profile_table (profile_id, lastupdate, creator_manager_id, description, creatorname, profile_name) VALUES (?, ?, ?, ?, ?, ?)
    bind => [115, 2011-04-01 15:37:13.257, 90, Newly created to check generation of id, Unspecified, Mahesh Babu Profile]

INSERT INTO profile_basket_table (action, from_node, profile_id) VALUES (?, ?, ?)
    bind => [4, 90, 1]

UPDATE profile_basket_table SET profile_id = ? WHERE ((profile_id = ?) AND (from_node = ?))
    bind => [1, 1, 90] 

Может ли кто-нибудь решить проблемы, о которых я упоминал в вышеупомянутой почте?

Я могу понять, почему он вставляет 1 во второй оператор вставки в profile_basket_table как 1значение по умолчанию.Но почему он обновляет 1 в столбце profile_id на profile_basket_table.

С помощью hibernate третье обновление обновляет полностью обновленный profile_id до 1130. Но почему eclipselink не обновляет profile_id из Profile в ProfileItem ???

Whyy ??

Может кто-нибудь ответить, пожалуйста?Где так называемая мобильность ??Это известные ошибки с eclipselink?

Спасибо.

Арун Кандрегула.

1 Ответ

0 голосов
/ 04 апреля 2011

Первая проблема возникла из-за ошибки, исправленной в последней версии EclipseLink (2.3). Эта проблема, однако, из-за того, как вы ее определили - поле ProfileItem.profile_id отображается дважды. Однажды из-за того, как он отображается в ProfileItem через отображение keyId встроенного идентификатора, второй из-за того, что он также может быть установлен через отношение Profile-> ProfileItem. Как было предложено в другом сообщении на форуме для первой проблемы, лучший способ отобразить это было бы вместо этого иметь OneToMany с указателем Back ManyToOne для установки profile_tem profile_id. Это заставит JPA установить значение вместо приложения, которому нужно получить значение из профиля и вручную установить его в keyId.

...