Java lombok对jpa有副作用吗
我正在将jpa实体转换为使用lombok。生成的代码如下所示:Java lombok对jpa有副作用吗,java,jpa,lombok,Java,Jpa,Lombok,我正在将jpa实体转换为使用lombok。生成的代码如下所示: @Entity @Table(name = "TEST") @Data @NoArgsConstructor @AllArgsConstructor class Test { ... @Column(name = "FORMATTING") @Enumerated(EnumType.ORDINAL) private FormatType formatType; ... } @Entity @Table
@Entity
@Table(name = "TEST")
@Data
@NoArgsConstructor
@AllArgsConstructor
class Test {
...
@Column(name = "FORMATTING")
@Enumerated(EnumType.ORDINAL)
private FormatType formatType;
...
}
@Entity
@Table(name = "TEST")
@Setter
class Test {
...
@Getter(onMethod=@__({
@Column(name = "FORMATTING"),
@Enumerated(EnumType.ORDINAL)
}))
private FormatType formatType;
...
}
产生的错误消息包含以下内容
Caused by: org.hibernate.HibernateException: Missing column: formatType in TEST
我真的不知道在这里搜索什么。(在formatType
进入谷歌之前,我尝试过将所有内容粘贴到谷歌上,但什么都没看到)
注:
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
应该是功能性的
我已经回滚了lombok的更改,我仍然想知道问题是什么,但没有匆忙。另外,多亏了这个可爱的小虫子,我落后了4个小时,所以我的反应可能有点慢
子表的pk是父表的fk,如果没有lombok,一切看起来都正常,尽管子类没有id
解决方案:
public enum FormatType {
FIRST_TYPE, SECOND_TYPE
}
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();
}
}
我完全忘了问这个问题。不久前,我重新讨论了这个问题。为了解释这个解决方案,让我们看一下我包含的第一个示例的稍微简化的版本
@Entity
@Table(name = "TEST")
@Setter
@Getter
class Test {
...
@Column(name = "FORMATTING")
@Enumerated(EnumType.ORDINAL)
private FormatType formatType;
...
}
Lombok似乎会给你这个:
@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查找错误列名的原因)。因此,我们实际上需要:
@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;
}
...
}
在经历了大量的困惑之后,我试图找到一些例子,并填写一些关于龙目山如何运作的细节(公平地说,我很容易困惑),我发现了这个小宝石:。利用这一功能,我得出了以下结论:
@Entity
@Table(name = "TEST")
@Data
@NoArgsConstructor
@AllArgsConstructor
class Test {
...
@Column(name = "FORMATTING")
@Enumerated(EnumType.ORDINAL)
private FormatType formatType;
...
}
@Entity
@Table(name = "TEST")
@Setter
class Test {
...
@Getter(onMethod=@__({
@Column(name = "FORMATTING"),
@Enumerated(EnumType.ORDINAL)
}))
private FormatType formatType;
...
}
当然,它是有效的。现在我们有了显然是唯一可用的解决方案,我想解决我们目前都在思考的问题:这真的比手动编写方法并附加注释更干净吗?答:。。。我不知道。我很高兴找到了解决办法。真奇怪。你能展示更多的代码吗?
我正试着写一个简单的项目,其中有一部分代码,就像你的问题中所说的那样,它成功了。我使用了SpringBoot和MySQL。尝试检查您的配置。这是我的代码:
枚举:
public enum FormatType {
FIRST_TYPE, SECOND_TYPE
}
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();
}
}
MySQL中的表:
public enum FormatType {
FIRST_TYPE, SECOND_TYPE
}
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();
}
}
实体:
public enum FormatType {
FIRST_TYPE, SECOND_TYPE
}
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();
}
}
存储库:
public enum FormatType {
FIRST_TYPE, SECOND_TYPE
}
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();
}
}
import org.springframework.data.jpa.repository.JpaRepository;
导入org.springframework.stereotype.Repository;
@存储库
公共接口测试存储库扩展了JpaRepository{
}
服务:
public enum FormatType {
FIRST_TYPE, SECOND_TYPE
}
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();
}
}
import org.springframework.beans.factory.annotation.Autowired;
导入org.springframework.stereotype.Service;
导入java.util.List;
@服务
公共类测试服务{
私有测试库;
@自动连线
公共TestService(TestRepository存储库){
this.repository=存储库;
}
公共列表getAllTestEntities(){
返回repository.findAll();
}
}
lombok不太可能导致运行时问题,因为它在预编译时工作,您可能会发现反编译生成的代码很有用,我有时发现lombok注释在源代码中的放置顺序会影响最终结果,因此,您使用@Data和@noargsconstuctor,我想你可以删除@noargsconstuctor,看看这是否解决了你的问题。我在Lombok和JPA上遇到了同样的问题,但我设置了Lombok,它按预期工作。代码如下:
控制器
package com.sms.controller;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.sms.model.StudentModel;
import com.sms.persistance.StudentRepository;
@RestController
public class StudentController {
@Autowired
private StudentRepository sr;
@PostMapping("/addstudent")
public String addStudent(@Valid @RequestBody StudentModel studentModel) {
StudentModel result = sr.save(studentModel);
return result.equals(null)?"Failed":"Successfully Saved student data";
}
}
型号
package com.sms.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.Data;
import lombok.RequiredArgsConstructor;
@Data
@RequiredArgsConstructor
@Entity
@Table(name="student", schema="development")
public class StudentModel {
@Id
@Column(name="student_id")
private int id;
@Column(name="student_name")
private String studentname;
@Column(name="student_address")
private String studentaddress;
}
存储库
package com.sms.persistance;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.sms.model.StudentModel;
@Repository
public interface StudentRepository extends JpaRepository<StudentModel, Integer>{
}
package com.sms.persistence;
导入org.springframework.data.jpa.repository.JpaRepository;
导入org.springframework.stereotype.Repository;
导入com.sms.model.StudentModel;
@存储库
公共界面StudentRepository扩展了JpaRepository{
}
您具体何时收到错误消息?当hibernate处理persistence infoPost时,这是一个再现该问题的完整示例。发布实际生成的Java代码也会很有帮助:使用反编译器来反编译生成的类,看看它是什么样子。我会处理这个问题,但同时,我认为这意味着lombok不应该有jpa相关的副作用,lombok只是一个编译时的东西。在新的示例中,使用经过净化的sql有点困难。但是,是的,这正是我的示例的目的。谢谢你花了额外的时间这是一个编译时问题是的,这对我来说也很有效-删除了NoArgsConstructor和RequiredArgsConstructor-我在运行时被重复的NotNull约束定义错误所困扰我把@Data
放在任何其他JPA注释之前的第一个位置,不知何故它是有效的,但我还不确定它是关于实体类中的注释顺序,还是在一起使用lombok
和JPA
时的那种间歇性的东西