Hibernate выполняет обновление и удаление на пользовательском JPQL - PullRequest
0 голосов
/ 11 октября 2019

Однако я пытаюсь обновить поля сущности, имеющей отношение ManyToMany, поскольку я просто хочу обновить поля таблицы и игнорировать отношение ManyToMany. Взаимосвязь между сущностями Company и UserSystem была определена в связи с тем, что company_user_system является таблицей объединения сущностей. Проблема заключается в том, что при выполнении моего обновления в компании, всегда перед моим обновлением, Hibernate делает обновление в компании и удаляет отношения в user_system_company, и это стирает отношения между Company и UserSystem, и я не понимаю, почему эти два запроса происходят, если яне выполняйте.

Это запросы, первый и второй не выполняются моим кодом:

Hibernate: update company set active=?, email=?, identification_code=?, trading_name=?, update_on=? where id=?
Hibernate: delete from company_user_system where company_id=?
Hibernate: update company set email=?, phone=?, corporate_name=?, trading_name=?, identification_code=?, email=?, phone2=? where id=?
Hibernate: select company0_.id as id1_0_, company0_.active as active2_0_, company0_.corporate_name as corporat3_0_, company0_.created_on as created_4_0_, company0_.email as email5_0_, company0_.email2 as email6_0_, company0_.identification_code as identifi7_0_, company0_.phone as phone8_0_, company0_.phone2 as phone9_0_, company0_.trading_name as trading10_0_, company0_.update_on as update_11_0_ from company company0_ where company0_.id=?

Ниже приведен код реализации обновления:

public class CompanyRepositoryImpl implements CompanyRepositoryCustom {

    @PersistenceContext
    private EntityManager entityManager;


    public Company updateCompanyFields(Company company) {

        // ... fieldSql implementation omitted

        String sql = "UPDATE Company SET "+ fieldsSql +" WHERE id = :id ";

        Query query = entityManager.createQuery(sql);

        // set the values for the fields
        for (Method method : getMethods) {
            query.setParameter(lowercaseFirstCharInString(cutGetInMethods(method.getName())), method.invoke(company));
        }

        // set id
        query.setParameter("id", company.getId());

        // execute update and search the database to return the updated object
        if (query.executeUpdate() == 1) {

            query = entityManager.createQuery("SELECT c FROM Company c WHERE c.id = :id");

            query.setParameter("id", company.getId());

            Company getCompany = (Company) query.getResultList().get(0);

            return getCompany;
        }

        return null;
    }
    // ... Other methods omitted
}

Код репозитория:

@Repository
public interface CompanyRepository extends JpaRepository<Company, Long>, JpaSpecificationExecutor<Company> , CompanyRepositoryCustom {

    @Modifying
    Company updateCompanyFields(Company company);
}

Код сущности компании, я только что добавил атрибуты, которые, как мне кажется, могут содержать что-то полезное для решения проблемы:

@Entity
@DynamicUpdate
@Table(name = "company")
public class Company implements Serializable {

    @CreationTimestamp
    @Column(name = "created_on", nullable = false)
    private Instant createdOn;

    @UpdateTimestamp
    @Column(name = "update_on")
    private Instant updateOn;

    @ManyToMany
    @JoinTable(
        name = "company_user_system",
        joinColumns = @JoinColumn(
            name = "company_id", referencedColumnName = "id"
        ),
        inverseJoinColumns = @JoinColumn(
            name = "user_system_id", referencedColumnName = "id"
        )
    )
    private Set<UserSystem> userSystems = new HashSet<>();
}

Класс UserSystem определяетотношения следующим образом:

@ManyToMany(mappedBy = "userSystems")
private Set<Company> companies = new HashSet<>();

Что может быть причиной этого обновления и удалить перед моим обновлением?

1 Ответ

1 голос
/ 13 октября 2019

Это происходит потому, что вы где-то изменили значения ваших отношений. EntityManager отслеживает такие изменения и помечает объект как грязный. При выполнении пользовательского запроса SQL Hibernate выполнит все ожидающие запросы (отправит любые грязные объекты).

Вы можете предотвратить это, вызвав EntityManager.clear().

...