线程在调用getResultList()时挂起

时间:2018-12-17 10:21:21

标签: java spring hibernate jpa

JPA有一个奇怪的问题。在我的sheduler中执行下一个代码

@SuppressWarnings("unchecked")
 @Transactional
 public void refreshSmsStatuses() {
    try {
        log.info("Enter refreshSmsStatuses");

        EntityManager em = hibernateHelper.getEntityManager();

        log.info("EM created");

        List<Sms> lSms = null;

        log.info("lSms = null;");

        TypedQuery<Sms> smsQuery = em.createQuery(
            "SELECT sms FROM Sms AS sms 
             join sms.status as status 
             WHERE status.isFinal = 0 
             and sms.remoteId is not null 
             and sms.sendDate > sysdate - 3", Sms.class);

        log.info("sqlQuery created");

        lSms = smsQuery.getResultList();

        log.info("Query SMS executed");
        .....

计划每晚重新启动后,它可以运行几次并挂起。还有下一个字符串

2018-12-17 00:10:33,802 [SmsDao.java:pool-2-thread-1:166] - lSms = null;
2018-12-17 00:10:33,802 [SmsDao.java:pool-2-thread-1:168] - sqlQuery created
日志文件中的

。该查询不在DB中执行,而是挂在JPA中的某个位置。问题仅在生产服务器上。挂起任何sheduler的方法后都无效,因为,我认为它们正在等待该方法的结束。 如果有人遇到类似问题,请帮助我。 非常感谢

已更新

@Table( name = "ZUSB_SMS") 
@Entity
public class Sms extends BaseModel {
    private static final long serialVersionUID = -3624326750555670797L;
    @Id
    @SequenceGenerator(name = "generator", sequenceName = "ZUSB_SMS_SEQ")
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "generator")
    @Column(name = "id")
    private Long id;
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "REF_SMS_TEMPLATE_ID", referencedColumnName = "id")
    private SmsTemplate template;
    @Column(name = "name")
    private String name;
    @Column(name = "send_date")
    private Date sendDate;
    @Column(name = "phone")
    private String phone;
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "REF_CLIENT_ID", referencedColumnName = "id")
    private Client client;
    @Column(name = "text")
    private String text;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "REF_SMS_STATUS_ID", referencedColumnName = "id")
    private SmsStatus status;


    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "REF_USER_ID", referencedColumnName = "id")
    private User user;
    @Column(name = "remote_id")
    private Long remoteId;
    private String log = "";

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "REF_CLE_STATUS_ID", referencedColumnName = "id")
    private SmsCleStatus cleStatus;
    @Column(name = "cle_text")
    private String cleText;
    @Column(name = "cle_id")
    private Long cleId;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public SmsTemplate getTemplate() {
        return template;
    }
    public void setTemplate(SmsTemplate template) {
        this.template = template;
    }
    public Date getSendDate() {
        return sendDate;
    }
    public void setSendDate(Date sendDate) {
        this.sendDate = sendDate;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
    public Client getClient() {
        return client;
    }
    public void setClient(Client client) {
        this.client = client;
    }
    public String getText() {
        return text;
    }
    public void setText(String text) {
        this.text = text;
    }
    public SmsStatus getStatus() {
        return status;
    }
    public void setStatus(SmsStatus status) {
        this.status = status;
    }
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
    public Long getRemoteId() {
        return remoteId;
    }
    public void setRemoteId(Long remoteId) {
        this.remoteId = remoteId;
    }
    public String getLog() {
        return log;
    }

    public void setLog(String log) {
        DateFormat df = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
        Date today = Calendar.getInstance().getTime();        
        String reportDate = df.format(today);
        if(log.equals(""))
            this.log = reportDate + " " + log;
        else
            this.log = this.log + "\n" + reportDate + " " + log;
    }

    public SmsCleStatus getCleStatus() {
        return cleStatus;
    }

    public void setCleStatus(SmsCleStatus cleStatus) {
        this.cleStatus = cleStatus;
    }

    public String getCleText() {
        return cleText;
    }

    public void setCleText(String cleText) {
        this.cleText = cleText;
    }

    public Long getCleId() {
        return cleId;
    }

    public void setCleId(Long cleId) {
        this.cleId = cleId;
    }






}

P.S。对不起,我的英语

1 个答案:

答案 0 :(得分:-1)

首先,您的查询不正确,因为您没有指定ON要加入的内容。其次,您无需显式join SmsStatus表,因为您已将其与@ManyToOne映射。

像这样更新您的查询-

TypedQuery<Sms> smsQuery = em.createQuery(
        "FROM Sms s                            
         WHERE s.status.isFinal = 0
         AND s.remoteId IS NOT NULL   
         AND s.sendDate > sysdate-3", Sms.class);

这可以解决问题。