Arhn - архитектура программирования

В java/jpa/hibernate не читается таблица базы данных, измененная из другой внешней программы

в первую очередь прошу прощения за мой плохой английский.

Моя проблема в том, что моя программа не читает запись таблицы, измененную из внешней программы.

Мой сценарий:

  1. Я использую таблицу в AS400/DB2
    | ТНОТА | ТКОЭЛ | ТКОММ |
    | АГГ | 000 | 123 |
    в таблице есть '123' в поле записи;
  2. запустите мою программу, она будет выполняться бесконечное время, каждые 30 секунд вызывая функцию funTable0f();
  3. в первом цикле после выполнения funTable0f() значение меняется с «123» на «XYZ»;
  4. обновить запись с помощью команды sql (не с помощью моей программы) sql; обновить tabel0f установить tcomm = 'ABC', где tnota = 'AGG и tcoel = '000';
  5. во втором цикле, во ВТОРОЙ точке останова, объект показывает мне старое значение «XYZ», а не «ABC»;
  6. всегда во втором цикле, в ТРЕТЬЕЙ контрольной точке, значение в таблице остается «ABC» и не обновляется с помощью «XYZ» (hiberante помнит, что значение просто «XYZ» и не применяет обновление?)

кажется, он работает с копией в кеше памяти table0f, а не с реальной таблицей моей таблицы as400.

AsTabel0fDao asTabel0fDao = new AsTabel0fDaoMng();

public static void main(String[] args){
    AsOasic0f cmd = null;
    Iterator<AsOasic0f> iter_cmd = null;
    while(true){
        // cmdLs = asOasic0fDao.getCmdToDo();
        cmdLs.addAll(asOasic0fDao.getCmdToDo());

        iter_cmd = cmdLs.iterator();
        while(iter_cmd.hasNext()){
            cmd = iter_cmd.next();
            log.info("Comando: " + cmd.toString());
            
            funTable0f();
        }

        try{
            Thread.sleep(30000);
        }catch(InterruptedException e){
        }
    }
}
[...]
private void funTable0f(){
// FIRST breackpoint

    AsTabel0f asTabel0f = asTabel0fDao.getDaTnotaTcoel("AGG", "000");

// SECOND breackpoint

    String tcomm = "XYZ";
    asTabel0f.setTcomm(tcomm);
    if(!(asTabel0fDao.update(asTabel0f))){
        chiudi();
    }

// THIRD brackpoint

}

первичный ключ класса:

import java.io.Serializable;
import javax.persistence.Embeddable;

@Embeddable
public class AsTabel0fPKey implements Serializable{
    private static final long serialVersionUID = 1L;

    private String tnota;
    private String tcoel;

    public AsTabel0fPKey(){     }

    public AsTabel0fPKey(String tnota, String tcoel){
        super();
        this.tnota = tnota;
        this.tcoel = tcoel;
    }

    // getters & setters

    @Override
    public String toString(){
        return "AsTabel0fPKey [tnota=" + tnota + ", tcoel=" + tcoel + "]";
    }
}

модель класса table0f:

    import java.io.Serializable;
    import javax.persistence.*;
    import it.cascino.oasi.dbas.model.pkey.AsTabel0fPKey;
    
    @Entity(name="Tabel0f")
    @NamedQueries({
        @NamedQuery(name = "AsTabel0f.findAllByTnota", query = "SELECT o FROM Tabel0f o WHERE o.id.tnota = :tnota order by o.id.tcoel"),
        @NamedQuery(name = "AsTabel0f.findByTnotaTcoel", query = "SELECT o FROM Tabel0f o WHERE o.id.tnota = :tnota and o.id.tcoel = :tcoel")
    })
    public class AsTabel0f implements Serializable{
        private static final long serialVersionUID = 1L;
        
        @EmbeddedId
        private AsTabel0fPKey id;
        private String tcomm;
        
        public AsTabel0f(){
            this.id = new AsTabel0fPKey();
        }
        
// getters & setters

        @Override
        public String toString(){
            return "AsTabel0f [id=" + id + ", tcomm=" + tcomm + "]";
        }
    }

настойчивость:

     <?xml version="1.0" encoding="UTF-8"?>
    <persistence version="2.1"
        xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="DB2AS400" transaction-type="RESOURCE_LOCAL">
            <properties>
                <property name="hibernate.connection.url" value="jdbc:as400://10.0.21.20/cas_dat;transaction isolation=none" />
                <property name="hibernate.connection.driver_class" value="com.ibm.as400.access.AS400JDBCDriver" />
                <property name="hibernate.connection.username" value="JAVAPGM" />
                <property name="hibernate.connection.password" value="password" />
                <property name="hibernate.connection.pool_size" value="1" />
                <property name="hibernate.dialect" value="org.hibernate.dialect.DB2400Dialect" />
                <property name="hibernate.show_sql" value="false" />
                <property name="hibernate.generate_statistics" value="false" />
                <property name="hibernate.use_sql_comments" value="false" />
                <property name="hibernate.connection.shutdown" value="true" />
            </properties>
        </persistence-unit>
    [...]
    </persistence>

фабрика менеджеров сущностей:

    import javax.persistence.EntityManager;
    import javax.persistence.EntityManagerFactory;
    import javax.persistence.EntityTransaction;
    import javax.persistence.Persistence;
    
    public class Resources{
        private EntityManagerFactory emfAs = null;
        private EntityManager emAs = null;
        private EntityTransaction utxAs = null;
    
        public Resources(){
            super();
            if(emfAs == null) {
                initAs();
            }
        }
        
        private void initAs(){
            emfAs = Persistence.createEntityManagerFactory("DB2AS400");
            emAs = emfAs.createEntityManager();
            utxAs = emAs.getTransaction();
        }
    
        public void close(){
            if(emfAs != null) {
                closeAs();
            }
        }
    
        private void closeAs(){
            emAs.close();
            emfAs.close();
        }
        
        public EntityManagerFactory getEmfAs(){
            return emfAs;
        }
        
        public void setEmfAs(EntityManagerFactory emfAs){
            this.emfAs = emfAs;
        }
        
        public EntityManager getEmAs(){
            return emAs;
        }
        
        public void setEmAs(EntityManager emAs){
            this.emAs = emAs;
        }
        
        public EntityTransaction getUtxAs(){
            return utxAs;
        }
        
        public void setUtxAs(EntityTransaction utxAs){
            this.utxAs = utxAs;
        }
    }

ДАО:

    public interface AsTabel0fDao{
        Boolean update(AsTabel0f o);
    
        AsTabel0f getDaTnotaTcoel(String tnota, String tcoel);
    
        void close();
    }

Управление:

    public class AsTabel0fDaoMng implements AsTabel0fDao, Serializable{
        private static final long serialVersionUID = 1L;
        private Resources res = new Resources();
        private EntityManager em = res.getEmAs();
        private EntityTransaction utx = res.getUtxAs();
    
    Logger log = Logger.getLogger(AsTabel0fDaoMng.class);
    
    public Boolean update(AsTabel0f o){
        try{
            try{
                utx.begin();
                log.info("aggiorna: " + o.toString());
                em.merge(o);
            }finally{
                utx.commit();
            }
        }catch(Exception e){
            log.fatal(e.toString());
            return false;
        }
        return true;
    }
    
    public AsTabel0f getDaTnotaTcoel(String tnota, String tcoel){
        AsTabel0f o = null;
        try{
            try{
                utx.begin();
                Query query = em.createNamedQuery("AsTabel0f.findByTnotaTcoel");
                query.setParameter("tnota", tnota);
                query.setParameter("tcoel", tcoel);
                o = (AsTabel0f)query.getSingleResult();
            }catch(NoResultException e){
                o = null;
            }
            utx.commit();
        }catch(Exception e){
            log.fatal(e.toString());
        }
        return o;
    }
    
    public void close(){
        res.close();
        log.info("chiuso");
    }
}

Надеюсь, я ясно выразился,
заранее спасибо,
Риккардо

29.07.2020

  • Вы ловите какие-либо ошибки с log.fatal(e.toString());? 29.07.2020
  • Во-первых, обратите внимание, что вам не нужна транзакция для чтения данных из уровня сохраняемости, как в getDaTNotaTcoel. Во-вторых: осознайте, что некоторые реализации JPA кэшируют данные в памяти. Тем не менее, проверьте три вещи: во-первых, не забудьте зафиксировать свои чистые команды обновления SQL при выполнении внешних приложений; во-вторых, включите журналы SQL в файле persistence.xml, чтобы вы могли видеть, правильно ли запрашивается база данных вашим приложением; наконец, попробуйте evict() вашего объекта до ваших запросов после внешнего обновления SQL. 29.07.2020
  • @JeneaVranceanu ничего не регистрирует 30.07.2020
  • @PauloAraújo, как вы и предложили, я удалил из getDaTNotaTcoel() функцию utx.begin(); и utx.commit(); 30.07.2020
  • @PauloAraújo Я добавляю функцию‹br/›public void evict(Object entity){ em.getEntityManagerFactory().getCache().evict(entity.getClass());}, вызываю ее после метода обновления, но проблема остается. Я читал, что evict() управляет кешем второго уровня, а не кешем сеанса, может быть, по этой причине он не работает нормально? 30.07.2020
  • Извините, я упомянул выселение, но я хотел использовать функцию EntityManager#detach. Пожалуйста, попробуйте снова использовать его. 31.07.2020
  • @PauloAraújo, ваше решение с функцией отсоединения идеально. большое спасибо 31.07.2020

Ответы:


1

Я решил с помощью EntityManager#detach, предложенного @PauloAraújo.

Я публикую решение для помощи другим в будущем.

в основном классе

    if(!(asTabel0fDao.update(asTabel0f))){
        chiudi();
    }
    asTabel0fDao.detach(asTabel0f);  // it solve my problem

на уроке менеджмента:

    public void detach(Object entity){
        em.detach(entity);
    }

Спасибо, Риккардо.

31.07.2020
Новые материалы

Коллекции публикаций по глубокому обучению
Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

Представляем: Pepita
Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

Советы по коду Laravel #2
1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

3 способа решить квадратное уравнение (3-й мой любимый) -
1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

Создание VR-миров с A-Frame
Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

Демистификация рекурсии
КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..