#Cannot invoke "Object.hashCode()" because "x" is null

1 messages · Page 1 of 1 (latest)

onyx forge
#

I'm working on spring security project and i get the above error.

  • I don't understand what the object is and what "x" is here.
  • I have an entity called ItemEntity with getter, setter, no args and all args constructor annotations. (from lombok)
  • I have used ItemRepository extends JpaRepository<ItemEntity,Integer>{}
  • I have ItemService and ItemServiceImpl interface and class.
    But when i use any service method inside another method i get this error.
loud kettleBOT
#

<@&987246584574140416> please have a look, thanks.

onyx forge
#

this file contains the code where it shows the error. Check the line 78 @GetMapping("/updateItem"). Here i get the error. findById doesn't work. I tried to call the findById method in other functions such as mapping for home page and it works there but not in updateItem endpoint method. Why is that?

#

I can confirm the following -

  • No null values are present in database tables.
  • I printed every entity using toString method and no null values were found.
  • All services and repositories are annotated.
  • Proper initalization of the services and repositories is done.
#

Please help

obtuse kelp
#

Where is the updateItem method?

onyx forge
#

this method is in democontroller file

obtuse kelp
#

Am I blind? No such method exists there and @GetMapping and a path updateItem doesn't really match

onyx forge
#

all paths are correct fyi

obtuse kelp
#

But it's still weird that the path is called updateItem and you call it with GET instead of PATCH

#

Anyway, in what line is the error exactly?

#

Is it really the method header?

onyx forge
#

ItemServiceImpl.findById(ItemServiceImpl.java:35)
line 35 of itemServiceImpl

obtuse kelp
#

Line 35 is what line? I don't have any line numbers here

onyx forge
#

public ItemEntity findById(int theId) {
Optional<ItemEntity> itemEntity = itemEntityRepository.findById(theId);
just go to ItemServiceImpl file and scroll down. at the very end would be this method

obtuse kelp
#

What does ItemEntity look like?

onyx forge
#

i removed lombok annotations i thought they were causing this issue. but still got the same error

obtuse kelp
#

For now I would suggest you using a debugger to see what may be wrong (where x actually is located) or you could try setting

  @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "username", referencedColumnName = "username", nullable = false)
    private UserEntity seller;

to null and don't fetch it from the DB (remove annotation) temporarily to see if this causes the error

onyx forge
#

let me try it.

#

now the application wont run. i added a breakpoint at the line optional itemEntity in itemserviceimpl.

#

@obtuse kelp

obtuse kelp
#

Well, it wont run because its a breakpoint. You have to step through manually

onyx forge
#

earlier it was running and i could see some info when i clicked on the button that called that findById method.
it just keep on loading localhost:8080.

#

this is a spring security project btw.

obtuse kelp
#

I just saw that you mentioned it works in the home page. Maybe just try generating the hashcode/equals methods in your entities? Have never seen such an error

onyx forge
#

ok

#

this is the first time it is happening to me. i think i have declared and initialized all variables properly.

#

i will give your answer a try.

onyx forge
#

i generated equals() and hashcode() methods using intellij ide and still the same error.

onyx forge
#
    public String getSomeValue(){
        try {
            ItemEntity itemEntity = itemService.findById(1);
        }
        catch (Exception e){
            System.out.println("couldnt find the object with id 1.");

        }
        return "home";
    }
    
    @GetMapping("/list")
    public String list(){

        List<ItemEntity> list = itemService.findAll();
        System.out.println(list);
        return "redirect:/";
    }```

no matter how many different mappings i make, it always gives an error. 
even findAll() gives error same as findById()
drowsy rain
#

If you have logging for the sql queries enabled, then you can check if the error is thrown after the query is logged, it should be after but just verify this.

Also you can jump into the implementation of the findAll() and findById() methods in the Implementations generated by Spring JPA during compile time the class should be an implementation of SimpleJPARepository or CrudRepository, and check the actual line in the source code that is causing the issue.

onyx forge
#

im calling findAll() function somewhere else and it is not giving this error. but in other endpoint functions it is giving this error. you can check the seller controller java file. in the method saveItem, it is working.

in demo controller too, this seems to work. but why does it not work anymore for new endpoints i dont understand.

drowsy rain
#

If it worked for some endpoints and not others, are u sure it's the findAll causing the issue?

onyx forge
#

like this output is from the demo controller.

@Controller
public class DemoController {

    private final UserService userService;
    private final FileUpload fileUpload;
    private final ItemService itemService;

    @Autowired
    public DemoController(UserService userService,
                          ItemService itemService,
                          FileUpload fileUpload) {
        this.userService = userService;
        this.fileUpload = fileUpload;
        this.itemService = itemService;
    }

    @GetMapping("/")
    public String showHome(Model theModel){
        List<UserEntity> users = userService.findAll();
        theModel.addAttribute("users",users);

        List<ItemEntity> items = itemService.findAll();
        theModel.addAttribute("items", items);
        ItemEntity itemEntity = itemService.findById(1);
        System.out.println(itemEntity);
        System.out.println(itemEntity.toString());
        return "home";
    }
}```

this is the code.
drowsy rain
#

Can you paste your security config

#

Or your general config, it could be a filter or some routine running before you main function that's causing the issue for new endpoitns

onyx forge
#

i dont think security config is stopping it because i can access other endpoints like changeProfilePhoto, changeUsername etc.

onyx forge
drowsy rain
#

You're sure it's getting to those methods right?

onyx forge
onyx forge
drowsy rain
#

Nope, that's not what I mean, the request made for those endpoints, You're sure that the request is getting to the controller method right?

onyx forge
#

yeah. i added some print statements. for getSomeValue() method, it is printing "hello" and then running the catch block
but for the second list method, it is simply giving error and not printing anythng

drowsy rain
#

But I don't see any line printing of "hello" in your code, or where is the code that prints the "hello"?

onyx forge
#
    public String getSomeValue(){
        System.out.println("hello from get some value");
        try {
            ItemEntity itemEntity = itemService.findById(1);
        }
        catch (Exception e){
            System.out.println("couldnt find the object with id 1.");

        }
        return "home";
    }

    @GetMapping("/list")
    public String list(){
        System.out.println("hello from list function");
        List<ItemEntity> list = itemService.findAll();
        System.out.println(list);
        return "redirect:/";
    }```
drowsy rain
#

Hmm, try and enable sql logging for the project, that is, to show all the queries that were executed for the findAll() method.
spring.jpa.show-sql=true

#

There should be some queries executed

onyx forge
#

i used another endpoint called "saveItem" and it saved the item in the database. database has all items from 1 to 3.
saveitem method also uses the item repository save method but its not giving error here.
findAll and findById give error in specifc areas.

onyx forge
#

Hibernate:
select ie1_0.id,ie1_0.details,ie1_0.image_url,ie1_0.name,ie1_0.price,ie1_0.quantity,s1_0.id,s1_0.email,s1_0.enabled,s1_0.firstname,s1_0.lastname,s1_0.password,s1_0.profile_photo,s1_0.username,a1_0.username,a1_0.authority,ie1_0.type from items ie1_0 left join users s1_0 on s1_0.username=ie1_0.username left join authorities a1_0 on s1_0.username=a1_0.username where ie1_0.id=?

#

this is the output query.

#

```create database if not exists inventory;
USE inventory;

DROP TABLE IF EXISTS authorities;
DROP TABLE IF EXISTS users;
DROP TABLE IF EXISTS items;

CREATE TABLE users (
id int primary key auto_increment,
username varchar(50) unique key NOT NULL,
firstname varchar(50) NOT NULL,
lastname varchar(50) NOT NULL,
email varchar(50) NOT NULL,
password varchar(60) NOT NULL,
enabled tinyint NOT NULL,
profile_photo varchar(200) DEFAULT "https://upload.wikimedia.org/wikipedia/commons/thumb/2/2c/Default_pfp.svg/2048px-Default_pfp.svg.png"
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO users (id, username,firstname, lastname, email, password,enabled)
VALUES
(1,'ben10000','Ben','Tennyson','[email protected]','$2a$12$E6xA14LnI.Ay/zqFdmrXGeCvdm/WpcCkXDrGou9Y7guQozx/Fj4pe',1),
(2,'jimmy','James','McGill','[email protected]','$2a$12$E6xA14LnI.Ay/zqFdmrXGeCvdm/WpcCkXDrGou9Y7guQozx/Fj4pe',1),
(3,'batman','Bruce','Wayne','[email protected]','$2a$12$E6xA14LnI.Ay/zqFdmrXGeCvdm/WpcCkXDrGou9Y7guQozx/Fj4pe',1);

-- Table structure for table authorities

CREATE TABLE authorities (
username varchar(50) NOT NULL,
authority varchar(50) NOT NULL,
UNIQUE KEY authorities_idx_1 (username,authority),
CONSTRAINT authorities_ibfk_1 FOREIGN KEY (username) REFERENCES users (username)
ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO authorities VALUES ('batman','ROLE_BUYER'), ('jimmy','ROLE_SELLER'), ('ben10000','ROLE_ADMIN');

CREATE TABLE items (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
image_url VARCHAR(200),
type VARCHAR(50) NOT NULL,
quantity INT NOT NULL,
price float NOT NULL,
details VARCHAR(255) NOT NULL,
username VARCHAR(50) NOT NULL,
CONSTRAINT fk_items_user
FOREIGN KEY (username) REFERENCES users (username)
ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

#

this is the sql query to create all the tables. users authorities and items

drowsy rain
#

Can you then copy the select query and run it manually, like in a console with the appropriate id replaced with '?'

#

Check for any nullable result

onyx forge
#

i ran this query and it gave a non null output

#
import java.sql.*;

public class ManualQueryRunner {
    public static void main(String[] args) {
        String url = "jdbc:mysql://localhost:3306/inventory";
        String username = "demo1";
        String password = "demo1";

        String query = """
            SELECT 
              ie1_0.id,
              ie1_0.details,
              ie1_0.image_url,
              ie1_0.name,
              ie1_0.price,
              ie1_0.quantity,
              s1_0.id,
              s1_0.email,
              s1_0.enabled,
              s1_0.firstname,
              s1_0.lastname,
              s1_0.password,
              s1_0.profile_photo,
              s1_0.username,
              a1_0.username,
              a1_0.authority,
              ie1_0.type
            FROM items ie1_0
            LEFT JOIN users s1_0 ON s1_0.username = ie1_0.username
            LEFT JOIN authorities a1_0 ON s1_0.username = a1_0.username
            WHERE ie1_0.id = ?
        """;

        try (
                Connection conn = DriverManager.getConnection(url, username, password);
                PreparedStatement stmt = conn.prepareStatement(query)
        ) {
            int idToCheck = 1; // You can change this to test other IDs
            stmt.setInt(1, idToCheck);

            ResultSet rs = stmt.executeQuery();

            if (!rs.next()) {
                System.out.println("No item found with ID = " + idToCheck);
            } else {
                System.out.println("Item found:");
                System.out.println("ID: " + rs.getInt("id"));
                System.out.println("Name: " + rs.getString("name"));
                System.out.println("Price: " + rs.getDouble("price"));
                System.out.println("User Email: " + rs.getString("email"));
                System.out.println("Authority: " + rs.getString("authority"));
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
drowsy rain
#

No, I mean, is there any column result that is null?

#

And you could run it manually in a console, you don't need to run a new java program for it

#

But it's still fine

onyx forge
#

nothing is null here.

#

shall i send you the project itself? because pasting code doesn't seem to be helping much.

modern turtle
#

Why not just place a breakpoint where the exception happens?

#

Clearly something is null if the exception is thrown.

#

Your stacktrace even says where.

drowsy rain
onyx forge
modern turtle
#

Or just write a test for it.

onyx forge
modern turtle
drowsy rain
#

But have u tried changing all relationships to lazy in you item entity class?

onyx forge
#

yeah i tried. still same.

vital valve
onyx forge
#

object.hashcode() cant be invoked

silent mantle
#

What in the world is AuthorityEntity

#

And why are you storing granted authorities in an entity, with an unchecked cast no less

drowsy rain
# onyx forge yeah i tried. still same.

Hmm, alright, can we try one last thing, I'm getting out of ideas, the query I told you about earlier, can your run it raw, like run in a console, or even though you want to use another java application, let it print all the results of the columns, in the code above you only printed some columns, but this time I want to see it all, that's the result from this query:

              ie1_0.id,
              ie1_0.details,
              ie1_0.image_url,
              ie1_0.name,
              ie1_0.price,
              ie1_0.quantity,
              s1_0.id,
              s1_0.email,
              s1_0.enabled,
              s1_0.firstname,
              s1_0.lastname,
              s1_0.password,
              s1_0.profile_photo,
              s1_0.username,
              a1_0.username,
              a1_0.authority,
              ie1_0.type
            FROM items ie1_0
            LEFT JOIN users s1_0 ON s1_0.username = ie1_0.username
            LEFT JOIN authorities a1_0 ON s1_0.username = a1_0.username
            WHERE ie1_0.id = ?
onyx forge
drowsy rain
#

mysql workbench is fine

onyx forge
#

ok