当前位置: 首页 > 知识库问答 >
问题:

在类中使用JpaRepository实现Runnable[复制]

阎安邦
2023-03-14

我正在使用Spring Boot创建套接字服务器,并且在实现Runnable的类中初始化我的JpaRepository时遇到了麻烦。为了测试服务器,我使用netcat,服务器成功接收数据并创建新的线程来处理/解析数据。但是当通过JpaRepository将数据保存在数据库中时,我会得到NullPointerExcure,因为仓库尚未成功初始化。我在配置中错过了什么?

我的SpringBoot应用程序

package is.siminn.aos;

import java.net.ServerSocket;

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class AosApplication {
    public static final Logger log = LogManager.getLogger(AosApplication.class);
    
    public static void main(String[] args) {
        SpringApplication.run(AosApplication.class, args);
        openSocket();
    }
    
    private static void openSocket() {
        try (ServerSocket server = new ServerSocket(1234)) {
            log.log(Level.INFO, "Server listening on port " + 1234);
            while (true) {
                Thread obj = new Thread(new AosTask(server.accept()));
                obj.start();
            }
        } catch (Exception e) {
            log.log(Level.ERROR, e.getMessage(), e);
        }
    }
}

类实现Runnable

package is.siminn.aos;

import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Date;

import javax.transaction.Transactional;

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import is.siminn.aos.domain.Alarm;
import is.siminn.aos.domain.AlarmCategory;
import is.siminn.aos.domain.AlarmClass;
import is.siminn.aos.domain.Exchange;
import is.siminn.aos.domain.Spr;
import is.siminn.aos.repositories.AlarmCategoryRepository;
import is.siminn.aos.repositories.AlarmClassRepository;
import is.siminn.aos.repositories.AlarmRepository;
import is.siminn.aos.repositories.ExchangeRepository;
import is.siminn.aos.repositories.SprRepository;
import is.siminn.aos.repositories.SubExchangeRepository;

public class AosTask implements Runnable {
    
    public static final Logger log = LogManager.getLogger(AosTask.class);
    
    Socket socket;
    
    AlarmClassRepository alarmClassRepository;

    AlarmCategoryRepository alarmCategoryRepository;

    ExchangeRepository exchangeRepository;

    SubExchangeRepository subExchangeRepository;
    
    SprRepository sprRepository;
    
    AlarmRepository alarmRepository;

    protected AosTask(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        System.out.println("Thread " + Thread.currentThread().getId() + " is running");
        int ascii = -1;
        
        try (InputStreamReader in = new InputStreamReader(socket.getInputStream())) {
            OutputStreamWriter out = new OutputStreamWriter(socket.getOutputStream());
            StringBuffer axeBlock = new StringBuffer();

            do {
                ascii = in.read();
                axeBlock.append((char) ascii);
            } while (ascii != 4);
            out.append(process(axeBlock));
            out.flush();

        } catch (Exception e) {
            log.log(Level.ERROR, e.getMessage(), e);
        } finally {
            try {
                socket.close();
            } catch (Exception e) {
                log.log(Level.ERROR, e.getMessage(), e);
            }
        }
    }
    
    @Transactional
    private String process(StringBuffer axeBlock) {
        String header1 = "";
        String header2 = "";
        Alarm alarm = null;
        boolean isAlarm = true;
        
        String[] axeBlockArray = axeBlock.toString().split("\\n|\\r|\\f");
        for (int i = 0; i < axeBlockArray.length; i++) {
            String line = axeBlockArray[i];

            
            if (line.startsWith(":type=alarm") || line.startsWith(":type=spontan")) { /* APG type */
                log.log(Level.DEBUG, "APG...");
                
                if (line.startsWith(":type=alarm")) {
                    String nextLine = axeBlockArray[i + 2];
                    
                    if (nextLine.startsWith("*** ALARM CEASING")) {
                        log.log(Level.DEBUG, "APG alarm ceasing");
                        isAlarm = false;
                        ceasing(nextLine);
                        break;
                    } else {
                        log.log(Level.DEBUG, "APG alarm");
                        header1 = nextLine;
                        alarm = alarm(header1);
                        header2 = axeBlockArray[i + 3];
                        break;
                    }

                } else if (line.startsWith("type=spontan")) {
                    log.log(Level.DEBUG, "APG heartbeat");
                    System.out.println("heartbeat");
                    isAlarm = false;
                    heartbeat(line);
                    break;
                } else {
                    /* wtf */
                }
                break;
            } else if (line.startsWith("WO      ")) { /* IOG type */
                log.log(Level.DEBUG, "IOG...");
                // TODO: implement
            } else {
                /* nothing to see here */
            }
        }
        
        if (isAlarm) {
            alarm.setSpr(new Spr(header1, header2, new String[] {axeBlock.toString()}));
        }
        return axeBlock.toString();
    }
    
    private Alarm alarm(String header1) {
        Alarm alarm = new Alarm();
        
        /**
         * Header example
         * header1: *** ALARM 406 A2/APT "TBREI/IS76/MPS1"A 220104 1404
         */
        String[] fields = header1.split(" ");

        Integer alarmId = Integer.valueOf(fields[2]);
        String[] alarmClassAndCategory = fields[3].split("/");
        String cls = alarmClassAndCategory[0];
        String cat = alarmClassAndCategory[1];
        String exch = fields[4].substring(1, fields[4].indexOf("/"));
        String date = fields[5];
        String time = fields[6];
        Date created = null;
        try {
            created = Utils.createTimestamp(date, time);
        } catch (Exception e) {
            // TODO: handle exception
        }
        
        AlarmClass alarmClass = alarmClassRepository.findByCode(cls);
        AlarmCategory alarmCategory = alarmCategoryRepository.findByCode(cat);
        Exchange exchange = exchangeRepository.findByCode(exch);
        
        alarm.setAlarmId(alarmId);
        alarm.setAlarmCategory(alarmCategory);
        alarm.setAlarmClass(alarmClass);
        alarm.setExchange(exchange);
        alarm.setDateCreated(created);
        
        return alarm;
    }
    
    private void ceasing(String line) {
        log.log(Level.DEBUG, "CEASING [" + line + "]");
        // TODO: implement
    }
    
    private void heartbeat(String line) {
        log.log(Level.DEBUG, "HEARTBEAT [" + line + "]");
        // TODO: implement
    }
}

应用性质

# ===============================
# = DATA SOURCE
# ===============================
# Set here configurations for the database connection
spring.datasource.url=jdbc:postgresql://localhost:5432/aos
spring.datasource.username=foo
spring.datasource.password=bar
spring.datasource.driver-class-name=org.postgresql.Driver
# Keep the connection alive if idle for a long time (needed in production)
spring.datasource.tomcat.test-while-idle=true
spring.datasource.tomcat.validation-query=SELECT 1


# ===============================
# = JPA / HIBERNATE
# ===============================
# Show or not log for each sql query
spring.jpa.show-sql=true
# Hibernate ddl auto (create, create-drop, update): with "create" the database
spring.jpa.hibernate.ddl-auto=create
#spring.jpa.hibernate.ddl-auto=update

# Naming strategy
spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyHbmImpl
spring.jpa.hibernate.naming.physical-strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy

# Allows Hibernate to generate SQL optimized for a particular DBMS
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.main.allow-bean-definition-overriding=true

我有几个存储库,它们以相同的方式实现,所以我只发布一个例子。

package is.siminn.aos.repositories;

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

import is.siminn.aos.domain.AlarmCategory;

@Repository
public interface AlarmCategoryRepository extends JpaRepository<AlarmCategory, Long> {
    AlarmCategory findByCode(String code);
}

实体也是相似的,所以我认为一个例子就足够了。

package is.siminn.aos.domain;

import java.io.Serializable;
import java.util.Objects;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import lombok.Data;

@Data
@Entity
@Table(name = "ALARM_CLASS")
public class AlarmClass implements Serializable {

    private static final long serialVersionUID = 1L;
    
    @Id
    @Column(name = "ID", nullable = false)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(name = "CODE", nullable = false, unique = true)
    private String code;

    public AlarmClass() {
        super();
        // TODO Auto-generated constructor stub
    }

    public AlarmClass(String code) {
        super();
        this.code = code;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    @Override
    public int hashCode() {
        return Objects.hash(code, id);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        AlarmClass other = (AlarmClass) obj;
        return Objects.equals(code, other.code) && id == other.id;
    }

    @Override
    public String toString() {
        return "AlarmClass [id=" + id + ", code=" + code + "]";
    }
    
}

SpringApplication日志

12:36:16.752 [Thread-0] DEBUG org.springframework.boot.devtools.restart.classloader.RestartClassLoader - Created RestartClassLoader org.springframework.boot.devtools.restart.classloader.RestartClassLoader@79f54323

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.6.2)

2022-01-14 12:36:16.997  INFO 65870 --- [  restartedMain] is.siminn.aos.AosApplication             : Starting AosApplication using Java 15.0.1 on IS-C02F62LZMD6R with PID 65870 (/Users/gsigurdsson/Documents/workspace-spring-tool-suite-4-4.8.0.RELEASE/aos/target/classes started by gsigurdsson in /Users/gsigurdsson/Documents/workspace-spring-tool-suite-4-4.8.0.RELEASE/aos)
2022-01-14 12:36:16.998  INFO 65870 --- [  restartedMain] is.siminn.aos.AosApplication             : No active profile set, falling back to default profiles: default
2022-01-14 12:36:17.027  INFO 65870 --- [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2022-01-14 12:36:17.337  INFO 65870 --- [  restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode!
2022-01-14 12:36:17.338  INFO 65870 --- [  restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JDBC repositories in DEFAULT mode.
2022-01-14 12:36:17.357  INFO 65870 --- [  restartedMain] .RepositoryConfigurationExtensionSupport : Spring Data JDBC - Could not safely identify store assignment for repository candidate interface is.siminn.aos.repositories.AlarmCategoryRepository. If you want this repository to be a JDBC repository, consider annotating your entities with one of these annotations: org.springframework.data.relational.core.mapping.Table.
2022-01-14 12:36:17.359  INFO 65870 --- [  restartedMain] .RepositoryConfigurationExtensionSupport : Spring Data JDBC - Could not safely identify store assignment for repository candidate interface is.siminn.aos.repositories.AlarmClassRepository. If you want this repository to be a JDBC repository, consider annotating your entities with one of these annotations: org.springframework.data.relational.core.mapping.Table.
2022-01-14 12:36:17.360  INFO 65870 --- [  restartedMain] .RepositoryConfigurationExtensionSupport : Spring Data JDBC - Could not safely identify store assignment for repository candidate interface is.siminn.aos.repositories.AlarmRepository. If you want this repository to be a JDBC repository, consider annotating your entities with one of these annotations: org.springframework.data.relational.core.mapping.Table.
2022-01-14 12:36:17.362  INFO 65870 --- [  restartedMain] .RepositoryConfigurationExtensionSupport : Spring Data JDBC - Could not safely identify store assignment for repository candidate interface is.siminn.aos.repositories.AosUserRepository. If you want this repository to be a JDBC repository, consider annotating your entities with one of these annotations: org.springframework.data.relational.core.mapping.Table.
2022-01-14 12:36:17.363  INFO 65870 --- [  restartedMain] .RepositoryConfigurationExtensionSupport : Spring Data JDBC - Could not safely identify store assignment for repository candidate interface is.siminn.aos.repositories.ExchangeRepository. If you want this repository to be a JDBC repository, consider annotating your entities with one of these annotations: org.springframework.data.relational.core.mapping.Table.
2022-01-14 12:36:17.365  INFO 65870 --- [  restartedMain] .RepositoryConfigurationExtensionSupport : Spring Data JDBC - Could not safely identify store assignment for repository candidate interface is.siminn.aos.repositories.HeartbeatRepository. If you want this repository to be a JDBC repository, consider annotating your entities with one of these annotations: org.springframework.data.relational.core.mapping.Table.
2022-01-14 12:36:17.366  INFO 65870 --- [  restartedMain] .RepositoryConfigurationExtensionSupport : Spring Data JDBC - Could not safely identify store assignment for repository candidate interface is.siminn.aos.repositories.SprRepository. If you want this repository to be a JDBC repository, consider annotating your entities with one of these annotations: org.springframework.data.relational.core.mapping.Table.
2022-01-14 12:36:17.367  INFO 65870 --- [  restartedMain] .RepositoryConfigurationExtensionSupport : Spring Data JDBC - Could not safely identify store assignment for repository candidate interface is.siminn.aos.repositories.SubExchangeRepository. If you want this repository to be a JDBC repository, consider annotating your entities with one of these annotations: org.springframework.data.relational.core.mapping.Table.
2022-01-14 12:36:17.368  INFO 65870 --- [  restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 26 ms. Found 0 JDBC repository interfaces.
2022-01-14 12:36:17.376  INFO 65870 --- [  restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode!
2022-01-14 12:36:17.377  INFO 65870 --- [  restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2022-01-14 12:36:17.409  INFO 65870 --- [  restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 29 ms. Found 8 JPA repository interfaces.
2022-01-14 12:36:17.667  INFO 65870 --- [  restartedMain] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
2022-01-14 12:36:17.698  INFO 65870 --- [  restartedMain] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 5.6.3.Final
2022-01-14 12:36:17.798  INFO 65870 --- [  restartedMain] o.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
2022-01-14 12:36:17.876  INFO 65870 --- [  restartedMain] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2022-01-14 12:36:18.014  INFO 65870 --- [  restartedMain] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
2022-01-14 12:36:18.027  INFO 65870 --- [  restartedMain] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.PostgreSQLDialect
Hibernate: drop table if exists activity cascade
Hibernate: drop table if exists alarm cascade
Hibernate: drop table if exists alarm_category cascade
Hibernate: drop table if exists alarm_class cascade
Hibernate: drop table if exists aos_user cascade
Hibernate: drop table if exists exchange cascade
Hibernate: drop table if exists heartbeat cascade
Hibernate: drop table if exists preferences cascade
Hibernate: drop table if exists spr cascade
Hibernate: drop table if exists sub_exchange cascade
Hibernate: create table activity (id  bigserial not null, alarm_id bytea not null, aosuser_id bytea not null, created timestamp not null, message varchar(2048), updated timestamp not null, primary key (id))
Hibernate: create table alarm (id  bigserial not null, alarm_category bytea not null, alarm_class bytea not null, alarm_id int4 not null, ceasing_time timestamp, date_created timestamp not null, exchange_id bytea not null, spr_id bytea not null, primary key (id))
Hibernate: create table alarm_category (id  bigserial not null, code varchar(255) not null, primary key (id))
Hibernate: create table alarm_class (id  bigserial not null, code varchar(255) not null, primary key (id))
Hibernate: create table aos_user (id  bigserial not null, user_name varchar(255) not null, primary key (id))
Hibernate: create table exchange (id  bigserial not null, code varchar(255) not null, primary key (id))
Hibernate: create table heartbeat (id  bigserial not null, exchange_id bytea, lastcall timestamp not null, primary key (id))
Hibernate: create table preferences (id  bigserial not null, aosuser_id bytea not null, paging_counter int4 not null, refresh_interval int4 not null, primary key (id))
Hibernate: create table spr (id  bigserial not null, header1 varchar(255) not null, header2 varchar(255) not null, message bytea not null, primary key (id))
Hibernate: create table sub_exchange (id  bigserial not null, code varchar(255) not null, exchange_id bytea not null, primary key (id))
Hibernate: alter table alarm_category add constraint UK_k23l5xnesa680kk6b7sfeo2tt unique (code)
Hibernate: alter table alarm_class add constraint UK_he7nncsa3mlq6baqdjyg8hycy unique (code)
Hibernate: alter table aos_user add constraint UK_kbd1svuqgedu877c6x9n0hspd unique (user_name)
Hibernate: alter table exchange add constraint UK_84nwdtjn33htwaelm1fun3s7r unique (code)
Hibernate: alter table sub_exchange add constraint UK_s46mwccobp5ktr1yh2o491uoo unique (code)
2022-01-14 12:36:18.732  INFO 65870 --- [  restartedMain] o.h.t.schema.internal.SchemaCreatorImpl  : HHH000476: Executing import script 'file:/Users/gsigurdsson/Documents/workspace-spring-tool-suite-4-4.8.0.RELEASE/aos/target/classes/import.sql'
Hibernate: INSERT INTO alarm_category (code) VALUES('APZ')
Hibernate: INSERT INTO alarm_category (code) VALUES('APT')
Hibernate: INSERT INTO alarm_category (code) VALUES('POWER')
Hibernate: INSERT INTO alarm_category (code) VALUES('EXT')
Hibernate: INSERT INTO alarm_class (code) VALUES('A1')
Hibernate: INSERT INTO alarm_class (code) VALUES('A2')
Hibernate: INSERT INTO alarm_class (code) VALUES('A3')
Hibernate: INSERT INTO alarm_class (code) VALUES('O1')
Hibernate: INSERT INTO alarm_class (code) VALUES('O2')
Hibernate: INSERT INTO alarm_class (code) VALUES('O3')
Hibernate: INSERT INTO exchange (code) VALUES('SMUT')
Hibernate: INSERT INTO exchange (code) VALUES('SBRE')
Hibernate: INSERT INTO exchange (code) VALUES('TBREI')
Hibernate: INSERT INTO exchange (code) VALUES('AKUR')
Hibernate: INSERT INTO exchange (code) VALUES('BREI')
Hibernate: INSERT INTO exchange (code) VALUES('EGIL')
Hibernate: INSERT INTO exchange (code) VALUES('ISAF')
Hibernate: INSERT INTO exchange (code) VALUES('KOPA')
Hibernate: INSERT INTO exchange (code) VALUES('MIDB')
Hibernate: INSERT INTO exchange (code) VALUES('MULI')
Hibernate: INSERT INTO exchange (code) VALUES('SELF')
Hibernate: INSERT INTO exchange (code) VALUES('VARM')
Hibernate: INSERT INTO exchange (code) VALUES('TMULI')
Hibernate: INSERT INTO exchange (code) VALUES('PRUF')
2022-01-14 12:36:18.922  INFO 65870 --- [  restartedMain] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2022-01-14 12:36:18.928  INFO 65870 --- [  restartedMain] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2022-01-14 12:36:19.368  INFO 65870 --- [  restartedMain] o.s.b.d.a.OptionalLiveReloadServer       : LiveReload server is running on port 35729
2022-01-14 12:36:19.385  INFO 65870 --- [  restartedMain] is.siminn.aos.AosApplication             : Started AosApplication in 2.625 seconds (JVM running for 3.313)
2022-01-14 12:36:19.388  INFO 65870 --- [  restartedMain] is.siminn.aos.AosApplication             : Server listening on port 1234
Thread 43 is running
2022-01-14 12:39:02.194 ERROR 65870 --- [       Thread-7] is.siminn.aos.AosTask                    : Cannot invoke "is.siminn.aos.repositories.AlarmClassRepository.findByCode(String)" because "this.alarmClassRepository" is null

java.lang.NullPointerException: Cannot invoke "is.siminn.aos.repositories.AlarmClassRepository.findByCode(String)" because "this.alarmClassRepository" is null
    at is.siminn.aos.AosTask.alarm(AosTask.java:157) ~[classes/:na]
    at is.siminn.aos.AosTask.process(AosTask.java:105) ~[classes/:na]
    at is.siminn.aos.AosTask.run(AosTask.java:65) ~[classes/:na]
    at java.base/java.lang.Thread.run(Thread.java:832) ~[na:na]

共有1个答案

冯淳
2023-03-14

这个实现有几个问题。有三种方法可以在spring应用程序中注入依赖项,您不需要遵循其中任何一种。

  1. 字段
  2. 方法
  3. 建造师

用适当的注释标记字段和Runnable,或者执行构造函数注入。考虑创建一个单独的服务类,而不是在RunnEnter中写入整个逻辑。最后,创建一个线程池,而不是每次生成一个新线程,否则应用程序可能会停止响应。

 类似资料:
  • 问题内容: 我习惯于使用类似JavaScript或类似Erlang的语言编写代码,在其中我可以轻松实现回调函数。现在,我必须用Java编写一些东西。我想出了如何执行这样的回调: 问题是:这是正确的方法吗? 问题答案: 像这样简单地将一个接口(回调实现)传递给您的可运行对象 和一切简单的教程,您需要了解线程 这里

  • 我想知道在哪里实现JpaRepository接口 但是这些接口的实现在哪里? 这些接口中的所有方法是如何工作的(如findAll、findById、deleteAll等)?

  • 我尝试在具有Runnable的类中使用通过实例化的对象实例,但我得到了 我经历了这一过程,但我尝试的所有解决方案仍然是相同的问题。 共享我的代码: 我把这个类称为其他类的可运行类 < code>executor.submit(新的MyClass("abc "," def ")。newRunnable()); 那么,我是不是做错了什么,或者有什么方法可以让我使用这个对象

  • 问题内容: 我有一个简单的Entitly类,(和单独类中的字段)。然后,我使用Spring Data()访问数据库(MySql),使用常规ID,查询可以正常工作,无论是Spring生成的查询还是我自己编写的查询。与我没有设法创建正确的查询。我想做的是选择所有id(发生某些情况的EmbeddedId字段之一),这里有一些代码示例,也许有人会知道如何解决它。 实体类: EmbeddedId类: 和存储

  • 这是我的代码: user.java UserController.java 结构: 提前谢谢

  • 问题内容: 考虑两个类。第一个是,其子类符合: 第二类继承自: 该代码无法编译,因为: 使用元类型值构造“ Vehicle”类类型的对象必须使用“ required”初始化程序。 因此,我继续添加所需的初始化程序: 现在,应用程序可以编译,并且对象可以正确响应。 两个问题: 为什么构造具有元类型的对象需要初始化程序?(看来我编写的初始化程序没有任何作用。) 我写错了什么,还是 应该 添加到初始化程