How to solve issues in NullPointerException in Spring boot Entity class

73 views Asked by At

Codes I wrote to define Entity classes are below which don't really have issues when compiling but do have issues in running.

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "evolutions")
@IdClass(value = EvolutionPkey.class)
public class Evolution {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "pokemon_id")
    private int pokemonId;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "form_id")
    private int formId;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "next_pokemon_id")
    private int nextPokemonId;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "next_form_id")
    private int nextFormId;

    @Column(nullable = false)
    private int stage;

    @ManyToOne
    @JoinColumn(name = "pokemon_id", referencedColumnName = "pokemon_id")
    private Pokemon pokemon;

}

@Data
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class EvolutionPkey implements Serializable{
    public int pokemonId;
    public int formId;
    public int nextPokemonId;
    public int nextFormId;
}

public class Pokemon {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "pokemon_id")
    private int pokemonId;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "form_id")
    private int formId;

    ・・・・

    @OneToMany(mappedBy = "pokemon", cascade=CascadeType.ALL)
    private List<Evolution> evolutions;
}

When actually using repository instance to get info in service class below, issues occur and it will throw NullPointerException.

@Autowired
private PokemonRepository pokemonRepository;
pokemonRepository.findByPokemonId(pokemonId)

pokemonRepository interface code is below:

public interface PokemonRepository extends JpaRepository<Pokemon, PokemonPkey>, JpaSpecificationExecutor<Pokemon> {
    public Optional<List<Pokemon>> findByPokemonId(int pokemonId);

}

the error message occuring is below:

Resolved [java.lang.NullPointerException: Cannot invoke "org.hibernate.metamodel.mapping.AttributeMapping.getStateArrayPosition()" because the return value of "org.hibernate.persister.entity.AbstractEntityPersister.findAttributeMapping(String)" is null]

if anyone who has some ideas of how to fix this issues, that'd be great! Thanks!

i triesd several other ways of writting but it never worked...

2

There are 2 answers

1
Filipe Cavalcanti On

the interface implementation is wrong. Your code is as follows

extends JpaRepository<Pokemon, PokemonPkey>

however, the second argument must be the type of the attribute that is annotated with @Id, in this case Integer.

next point, as your pokemonId attribute is the entity's identifier, you don't need to create a new method, just use .findById()

last point if you need your identifier to be composite (that is, the identifier to be more than one column) the attribute that is annotated with @Id must be a class containing the columns that will be the PK (in your example it must be the class EvolutionPKey).

in your Evolution Pkey class add the @Embeddable annotation

1
BJones On

Change Evolution class to properly use the co posite key class in the @Id property declaration.

public class Evolution {
    @Id
    private EvolutionPkey evolutionId;
    …

I’d also strongly suggest re-evaluating the need for a composite key here for this class, and consider replacing with the use of a simple surrogate key, such as in the following example.

I’m guessing the added complexity of a composite key is unwarranted in your usage. From the example you’ve provided, it’s clearly unnecessary. Composite keys should be used only when necessary as they certainly increase complexity in practice.

public class Evolution {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "evolution_id")
    private int evolutionId;
    …