使用实体作为DTO在Hibernate中。

huangapple go评论80阅读模式
英文:

Using Entity as DTO in Hibernate

问题

以下是翻译好的部分:

我正在尝试将一个实体用作DTO。在这里,我正在使用setter方法设置对象的数据,但当我获取数据时,查询会执行,尝试获取未保存在数据库中的对象。以下是我的代码。在MailJob和Mail Queue中设置数据,我在这里接收一个逗号分隔的电子邮件值列表:

List<String> emailList = Arrays.asList(mailQueueDto.getToMail().split(","));

List<MailQueue> mailQueues = new ArrayList<>();
MailJobs mailJobs = new MailJobs();
mailJobs.setFromEmail(mailQueueDto.getFromEmail());
mailJobs.setMailMessage(mailQueueDto.getMailMessage());
mailJobs.setSubject(mailQueueDto.getSubject());
mailJobs.setPassword(mailQueueDto.getPassword());
mailJobs.setId(null);
for (String en : emailList) {
    String[] parts = en.split(":");
    MailQueue m = new MailQueue();
    m.setEmail(parts[0]);
    m.setName(parts[1]);
    m.setMailJobs(mailJobs);
    mailQueues.add(m);
}
mailSchedulerService.pushQueue(mailQueues);

现在是pushQueue方法,在该方法中,我尝试获取相同的设置数据。我这样做是为了可重用性。只要使用get方法获取对象,它就会尝试合并到数据库中,这里不需要执行查询。

public void pushQueue(List<MailQueue> mailQueue) throws MessagingException {
    logger.info("Mail Q-->" + mailQueue);
    Session session = getSession();
    Transport t = session.getTransport();
    t.connect();
    try {
        for (MailQueue mQ : mailQueue) {
            //logger.debug("Market->>" + mQ );
            if(mQ.getEmail().isEmpty())
                continue;
            Message m = getMailMessage(session,
                    mQ.getMailJobs().getSubject(),
                    mQ.getMailJobs().getMailMessage().replace("%name%", mQ.getName()),
                    mQ.getMailJobs().getFromEmail(), mQ.getEmail());
            t.sendMessage(m, m.getAllRecipients());

            mailQueueService.deleteById(mQ.getId());
        }
    }
    catch (Exception e){
        e.printStackTrace();
    }
    finally {
        t.close();
    }
}

抛出以下异常:

org.springframework.dao.EmptyResultDataAccessException: No class >  MailQueue entity with id 0 exists!
	at org.springframework.data.jpa.repository.support.SimpleJpaRepository.lambda$deleteById$0(SimpleJpaRepository.java:176)
	at java.util.Optional.orElseThrow(Optional.java:290)
	at org.springframework.data.jpa.repository.support.Simp

Mail Queue实体:

package com.iitraa.alumnus.iitAlumnus.entity;

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.*;

import javax.persistence.*;

@Data
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class MailQueue  {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private  int id;
    private String name;
    private String email;
    @ManyToOne( cascade = CascadeType.ALL  ,fetch = FetchType.LAZY)
    private MailJobs mailJobs;

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

    public void setEmail(String email) {
        this.email = email;
    }

    public void setMailJobs(MailJobs mailJobs) {
        this.mailJobs = mailJobs;
    }

    public String getName() {
        return name;
    }

    public String getEmail() {
        return email;
    }
    
    @JsonIgnore
    public MailJobs getMailJobs() {
        return mailJobs;
    }

    public int getId() {
        return id;
    }

    public boolean isComplete() {
        return complete;
    }

    public void setComplete(boolean complete) {
        this.complete = complete;
    }
}

基本上,我正在尝试将此实体用作POJO,并使用其getter和setter方法来设置和获取数据而不保存,但查询会执行并引发错误。如何防止这种情况发生?

英文:

I am trying to use an entity as DTO. Here I am setting data using setter to the object but when I fetch data then query executes which tries to fetch the set object which is unsaved in database
The following is my code . Setting the data in MailJob and Mail Queue here I am receiving a comma separated list of email values :

List&lt;String&gt; emailList = Arrays.asList(mailQueueDto.getToMail().split(&quot;,&quot;));

List&lt;MailQueue&gt;  mailQueues = new ArrayList&lt;&gt;();
MailJobs mailJobs = new MailJobs();
mailJobs.setFromEmail(mailQueueDto.getFromEmail());
mailJobs.setMailMessage(mailQueueDto.getMailMessage());
mailJobs.setSubject(mailQueueDto.getSubject());
mailJobs.setPassword(mailQueueDto.getPassword());
mailJobs.setId(null);
for (String en : emailList) {
    String[] parts = en.split(&quot;:&quot;);
    MailQueue m = new MailQueue();
    m.setEmail( parts[0]);
    m.setName( parts[1]);
    m.setMailJobs(mailJobs);
    mailQueues.add(m);
}
mailSchedulerService.pushQueue(mailQueues);

Now pushQueue method in which I try to fetch the same set data. I am doing this for re usability. As soon as the object it fetch using get it tries to merge to data base a query execute which is not required here.

public void pushQueue( List&lt;MailQueue&gt; mailQueue) throws MessagingException {
    logger.info(&quot;Mail Q---&gt;&quot;+mailQueue);
    Session session = getSession();
    Transport t = session.getTransport();
    t.connect();
    try {
        for (MailQueue mQ : mailQueue) {
            //logger.debug(&quot;Market-&gt;&gt;&quot;+ mQ );
            if(mQ.getEmail().isEmpty())
                continue;
            Message m = getMailMessage(  session,
                    mQ.getMailJobs().getSubject(),
                    mQ.getMailJobs().getMailMessage().replace(&quot;%name%&quot;,mQ.getName()),
                    mQ.getMailJobs().getFromEmail(),mQ.getEmail());
            t.sendMessage(m, m.getAllRecipients());

            mailQueueService.deleteById(mQ.getId());
        }
    }
    catch (Exception e){
        e.printStackTrace();
    }
    finally {
        t.close();
    }
}

Following exception is throw as:

org.springframework.dao.EmptyResultDataAccessException: No class &gt;  MailQueue entity with id 0 exists!
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.lambda$deleteById$0(SimpleJpaRepository.java:176)
at java.util.Optional.orElseThrow(Optional.java:290)
at org.springframework.data.jpa.repository.support.Simp

Mail Queue Entity

package com.iitraa.alumnus.iitAlumnus.entity;

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.*;

import javax.persistence.*;

    @Data
    @Getter
    @Setter
    @NoArgsConstructor
    @AllArgsConstructor
    @Entity
    public class MailQueue  {
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private  int id;
        private String name;
        private String email;
        @ManyToOne( cascade = CascadeType.ALL  ,fetch = FetchType.LAZY)
        private MailJobs mailJobs;

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

        public void setEmail(String email) {
            this.email = email;
        }

        public void setMailJobs(MailJobs mailJobs) {
            this.mailJobs = mailJobs;
        }

        public String getName() {
            return name;
        }

        public String getEmail() {
            return email;
        }
        
        @JsonIgnore
        public MailJobs getMailJobs() {
            return mailJobs;
        }

        public int getId() {
            return id;
        }

        public boolean isComplete() {
            return complete;
        }

        public void setComplete(boolean complete) {
            this.complete = complete;
        }

    }

Basically I am trying to use this entity as POJO and its getter and setter to set and then get data without saving but what the query is executed and the error is thrown. How to prevent this?

答案1

得分: 2

删除以下代码,因为它可能会触发并删除数据库中相关的对象。

mailQueueService.deleteById(mQ.getId());

英文:

Remove the following code as it may invoke and delete the related object in database

mailQueueService.deleteById(mQ.getId());

答案2

得分: 0

你在调用 getId() 方法之前没有将 MailQueue 保存到数据库中。

你的 id 被注解为 @GeneratedValue(strategy = GenerationType.AUTO),因此字段 id 的值只会由数据库自动生成。

在将 MailQueue 实体发送到 mailSchedulerService.pushQueue 之前尝试保存每个实体。

可能还需要在会话上执行 flush 操作。

英文:

You are not saving MailQueue in database before consuming getId() method.

You id is annotated with @GeneratedValue(strategy = GenerationType.AUTO), so the value of field id will only popupated by database.

Try to save every MailQueue entity before send it to mailSchedulerService.pushQueue.

Maybe a flush on session will be necessary too.

huangapple
  • 本文由 发表于 2020年7月28日 03:53:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/63122573.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定