龙目岛是否对jpa有副作用 [英] does lombok have side effects on jpa

查看:59
本文介绍了龙目岛是否对jpa有副作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在转换一个jpa实体以使用lombok.结果代码如下:

I am working on converting a jpa entity to use lombok. The resulting code is the following:

@Entity
@Table(name = "TEST")
@Data
@NoArgsConstructor
@AllArgsConstructor
class Test {
   ...
   @Column(name = "FORMATTING")
   @Enumerated(EnumType.ORDINAL)
   private FormatType formatType;
   ...
}

产生的错误消息包含以下内容

The resulting error message contains the following

Caused by: org.hibernate.HibernateException: Missing column: formatType in TEST

我真的不确定在这里用谷歌搜索什么. (我尝试将formatType之前的所有内容粘贴到Google中-没看到任何内容)

I am really not sure what to google here. (I tried pasting everything before formatType into google - didn't see anything)

    为了简洁和保密起见,
  1. 字段已重命名,并且省略了看起来不相关的方面.如果看起来像错字,那可能就是错字.请让我知道是否您注意到了什么,以便我解决.

  1. fields have been renamed and aspects which do not appear relevant have been omitted, for the sake of brevity and privacy. if something looks like a typo, it probably is. please let me know if you notice something so that i can address it.

描述该字段的3行与我正在使用的代码

the 3 lines describing the field are unchanged from the code i'm working with

我刚刚在出现错误消息之前就注意到了这一点

I just noticed this right before the error message

13:22:19,967 INFO  [org.hibernate.tool.hbm2ddl.TableMetadata] (ServerService Thread Pool -- 57) HHH000261: Table found: TABLE
13:22:19,967 INFO  [org.hibernate.tool.hbm2ddl.TableMetadata] (ServerService Thread Pool -- 57) HHH000037: Columns: [..., formatType, ...]
13:22:19,968 ERROR [org.jboss.msc.service.fail] (ServerService Thread Pool -- 57) MSC000001: Failed to start service jboss.persistenceunit."...": org.jboss.msc.service.StartException in service jboss.persistenceunit."...": javax.persistence.PersistenceException: [PersistenceUnit: ...] Unable to build EntityManagerFactory

应该起作用

  @Entity
  @Inheritance(strategy = InheritanceType.JOINED)
  @Table(name = "PARENT")

  public abstract class Parent implements Serializable {

     private static final long serialVersionUID = 1;
     @Id
     @Column(name = "ID")
     @GeneratedValue
     private long id;
     @Column(name = "ENABLED")
     private boolean enabled;
  }

  @Entity
  @Table(name = "CHILD")
  @Data
  @NoArgsConstructor
  @AllArgsConstructor
  public class Child extends Parent {
     /** XXX: HERE BE DRAGONS */
     @Column(name = "ENUM_1")
     @Enumerated(EnumType.STRING)
     private Enum1 enum1;
     @Column(name = "ENUM_2")
     @Enumerated(EnumType.ORDINAL)
     private Enum2 enum2;
     /** XXX: NO MORE DRAGONS */
     @Column(name = "FREQUENCY")
     private String frequency;
     @Column(name = "EMPTY")
     private boolean empty;
     @Column(name = "MAX_SIZE")
     private int maxSize;
  }
  public enum Enum1 {
     A,
     B,
     C
  }
  public enum Enum2 {
     X,
     Y,
     Z
  }

我已经取消了龙目岛的更改,我仍然想知道问题出在哪里,但不要着急.另外,由于这个可爱的小虫子,我比现在晚了大约4个小时,所以我的回复可能会有点慢.

I have rolled back the lombok changes, I would still like to know what the issue is, but there is no rush. Also, thanks to this lovely little bug i am about 4 hours behind so i may be a little slow on the responses.

子表的pk是父表的fk,并且即使Child类没有id,没有lombok的一切似乎都可以正常工作.

The pk of the child table is an fk to the parent table, and without lombok everything appears to work, despite the fact that the Child class has no id.

解决方案:

我完全忘记了问这个问题.不久前,我重新讨论了这个问题.为了解释该解决方案,让我们看一下我所包含的第一个示例的简化版本.

I completely forgot about asking this. Not long ago I revizited this problem. To explain the solution lets look at a slightly simplified version of the first example i included.

@Entity
@Table(name = "TEST")
@Setter
@Getter
class Test {
   ...
   @Column(name = "FORMATTING")
   @Enumerated(EnumType.ORDINAL)
   private FormatType formatType;
   ...
}

龙目岛似乎会给你这个:

It would appear that Lombok will give you this:

@Entity
@Table(name = "TEST")
class Test {
   ...
   @Column(name = "FORMATTING")
   @Enumerated(EnumType.ORDINAL)
   private FormatType formatType;

   public FormatType getFormatType() {
      return formatType;
   }
   public void setFormatType(FormatType formatType) {
      this.formatType = formatType;
   }
   ...
}

请注意,注释仍附加到字段.现在,我不确定是否只是我们正在使用的JPA的版本或实现,但我收集到,如果定义了访问器,jpa只会忽略除@Column之外的任何注释(以及为@Column指定的任何参数-这就是为什么jpa寻找错误的列名的原因).所以我们实际上需要:

Note that the annotations are still attached to the field. Now, I am not certain if it is just the version or implementation of JPA that we are using but I gather that if an accessor is defined jpa just ignores any annotations besides @Column (as well as any parameters specified for @Column - which is why jpa was looking for the wrong column name). So we actually need:

@Entity
@Table(name = "TEST")
class Test {
   ...
   private FormatType formatType;

   @Column(name = "FORMATTING")
   @Enumerated(EnumType.ORDINAL)
   public FormatType getFormatType() {
      return formatType;
   }
   public void setFormatType(FormatType formatType) {
      this.formatType = formatType;
   }
   ...
}

经过大量混乱,试图查找示例并填写有关龙目岛如何做事的一些细节(公平的说,我很容易混淆),我发现了这个小宝石:

After a great deal of confusion trying to find examples and fill in some specifics regarding how lombok does its thing (to be fair I am very easily confused) i discovered this little gem: onMethod=@__({@AnnotationsHere}). Utilizing this feature I came up with the following:

@Entity
@Table(name = "TEST")
@Setter
class Test {
   ...
   @Getter(onMethod=@__({
         @Column(name = "FORMATTING"),
         @Enumerated(EnumType.ORDINAL)
      }))
   private FormatType formatType;

   ...
}

并且可以正常工作.现在,我们已经有了显然是我想解决的问题的唯一可用的解决方案,这是我们目前正在思考的问题:除了手动编写方法并在其中附加注释之外,真的还有其他更清洁的方法吗?答:...我不知道.我很高兴找到解决方案.

And presto it works. Now that we have what is apparently the only available solution I would like to address the question we are all pondering at the moment: is that really any cleaner than just writing the method manually and attaching the annotations there? Answer: ... I have no idea. I am just happy I found a solution.

推荐答案

这很奇怪.您可以显示更多代码吗? 我正在尝试用您的问题中的一部分代码编写一个简单的项目,并且它可以正常工作.我使用了Spring Boot和MySQL.尝试检查您的配置.有我的代码:

Its strange. Can you show more code? I'm trying to write a simple project with part of code like in your question and it worked. I used Spring Boot and MySQL. Try to check your configuration. There is my code:

枚举:

public enum FormatType {

    FIRST_TYPE, SECOND_TYPE
}

MySQL中的表:

create table TEST
(
    ID int auto_increment primary key,
    FORMATTING int not null
);

实体:

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.*;

@Entity
@Table(name = "TEST")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Test {

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

    @Column(name = "FORMATTING")
    @Enumerated(EnumType.ORDINAL)
    private FormatType formatType;
}

存储库:

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface TestRepository extends JpaRepository<Test, Integer> {
}

服务:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class TestService {

    private TestRepository repository;

    @Autowired
    public TestService(TestRepository repository) {
        this.repository = repository;
    }

    public List<Test> getAllTestEntities() {
        return repository.findAll();
    }
}

这篇关于龙目岛是否对jpa有副作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆