2016-12-25 2 views
0

У меня есть простой код, как:Повторяющиеся результаты с Hibernate, Spring, MySQL 5.7, Ломбок

@Transactional(readOnly = true, timeout = 10) 
public List<MyClass> findThem() { 

    Criteria criteria = getSession().createCriteria(MyClass.class); 

    @SuppressWarnings("unchecked") 
    List<MyClass> theList = criteria.list(); 
    return theList; 
} 

Когда я использую это для запроса, я получаю обратно 942 пунктов, с дублированием элементов в списке. Я не вижу шаблона, о котором они еще дублируются.

Если я напрямую обращаюсь к БД, я возвращаю 138 записей. 138 является правильное число результатов:

SELECT count(*) FROM theschema.MY_CLASS;

Я попытался с помощью класса и без Ломбок @EqualsAndHashCode(exclude="id") на MyClass, а также просто не включая любые equals() реализацию, думая, что это дело - но не повезло.

Недавно я обновился от MySQL 5.6 до MySQL 5.7.17, но я все еще на Hibernate 4.3.8.Final и HikariCP 2.5.1. В запросе нет предложений WHERE или что-то очень сложное. Это может быть неважно, но я нахожусь на весне 4.3.3.RELEASE с mysql-connector-java 5.1.39.

Любые другие предложения, где искать? Я собираюсь включить больше протоколов отладки и заглянуть ближе.

Update:

Я могу correct this с criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);, но не уверен, почему это сейчас необходимо.

Update 2

Вот MyClass. У этого есть более основные свойства, но я вычитал их для краткости. Некоторые имена переименованы в целях конфиденциальности.

import base.domain.model.Persistable; 
import lombok.Getter; 
import lombok.NoArgsConstructor; 
import lombok.Setter; 
import org.hibernate.validator.constraints.NotEmpty; 

import javax.persistence.*; 
import java.math.BigDecimal; 
import java.util.*; 

@NoArgsConstructor 
@Entity 
@Table(name = "MY_CLASS") 
public class MyClass implements Persistable { 

    @Getter 
    @Setter 
    @Id 
    @Column(name = "MY_CLASS_ID") 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Integer id; 

    @Getter 
    @Setter 
    private ClassB classb; 

    @Getter 
    @Setter 
    @ManyToOne 
    @JoinColumn(name = "CLASS_C_ID") 
    private ClassC classC; 

    @Getter 
    @Setter 
    @Transient 
    private Integer daysOpen; 

    @Getter 
    @Setter 
    @OneToOne 
    @JoinColumn(name = "CLASS_D_ID") 
    private ClassD classD; 

    @Getter 
    @Setter 
    @NotEmpty 
    private String briefDescription; 

    @Getter 
    @Setter 
    @Column(length = 1000) 
    private String details; 

    @Getter 
    @Setter 
    @OneToOne 
    @JoinColumn(name = "COMPANY_ID") 
    private Company company; 

    @Getter 
    @Setter 
    @Transient 
    private BigDecimal cost; 

    @Getter 
    @Setter 
    @ManyToMany(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}) 
    @JoinTable(name = "MY_CLASS_TAG", 
      foreignKey = @ForeignKey(name = "FK_MY_CLASS_TAG_REQUEST"), 
      joinColumns = @JoinColumn(name = "MY_CLASS_ID"), 
      inverseJoinColumns = @JoinColumn(name = "TAG_ID")) 
    private Set<Tag> tags = new HashSet<>(10); 

    @Getter 
    @Setter 
    @ManyToMany(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}) 
    @JoinTable(name = "MY_CLASS_ASSIGNEE", 
      foreignKey = @ForeignKey(name = "FK_MY_CLASS_ASSIGNEE"), 
      joinColumns = @JoinColumn(name = "MY_CLASS_ID"), 
      inverseJoinColumns = @JoinColumn(name = "ASSIGNEE_ID")) 
    private Set<Account> assignees = new HashSet<>(0); 

    @Getter 
    @Setter 
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "myClass") 
    private List<MyClassHistory> historyList = new ArrayList<>(1); 

    private static final long serialVersionUID = 1L; 
} 

Update 3:

Я также возможность получить правильные результаты, используя HQL (сокращенная) без результата трансформатора:

String hql = "from MyClass myClass"; 
    Query q = getSession().createQuery(hql); 
    List<MyClass> myClasses = q.list(); 
    return myClasses; 

Going сравнить вывод SQL для каждого (есть много результатов, чтобы попытаться понять).

+1

Имеет ли ваш класс myclass много отношения к другому объекту. Если да, то он может дать вам повторяющиеся записи через спящий режим, если тип выборки определяется как нетерпеливый в отношениях от одного до многих. –

+0

Проверьте http://stackoverflow.com/questions/1560239/is-it-valid-for-hibernate-list-to-return-duplicates – Justas

+0

@PushpendraPal хорошая мысль, но нет типов выборки EAGER. – bphilipnyc

ответ

0

должно быть какое-то соединение в запросе, которое увеличивает количество результатов и, следовательно, ваш счет, часто я сталкиваюсь с подобной проблемой, вы можете попытаться взять данные в Set вместо списка или понаблюдать за фактическим запросом, запущенным в БД.

+0

Как указано, MyClass использует Sets, за исключением последнего свойства, и мне нужно, чтобы он был List, поскольку он должен допускать дубликаты. SQL-запрос действительно задействован, но попытается добраться до него. – bphilipnyc