JDBC/SQL - ID is always 0 - sql

so i'm trying to insert an hardcoded member to my Members table. I'm using Spring Boot & JDBC on Eclipse.
This is my schema.sql:
CREATE TABLE Members
(
ID int not null,
LastName varchar(255) not null,
FirstName varchar(255) not null,
PhoneNumber integer not null,
created timestamp not null,
primary key(ID)
);
INSERT INTO MEMBERS (ID, LASTNAME, FIRSTNAME,PHONENUMBER, CREATED)
VALUES(1001, 'Max', 'Mad', 0547547547, sysdate());
i got a findAll method in a DAO class:
public List<Member> findAll(){
return jtemp.query("select * from members", new BeanPropertyRowMapper<Member>(Member.class));
}
when i run it, it returns:
[Member [id=0, firstName=Mad, lastName=Max, phoneNumber=547547547, created=2017-10-31 18:57:21.606]]
As you can see the ID wasn't inserted for some reason.
my Member class is like this:
public class Member {
private long id;
private String firstName;
private String lastName;
private long phoneNumber;
private Date created;
public Member(long id, String firstName, String lastName, long phoneNumber, Date created) {
super();
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.phoneNumber = phoneNumber;
this.created = created;
}
public long getUserId() {
return id;
}
public void setUserId(long userId) {
this.id = userId;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public long getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(long phoneNumber) {
this.phoneNumber = phoneNumber;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
#Override
public String toString() {
return "Member [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", phoneNumber="
+ phoneNumber + ", created=" + created + "]";
}
}
How can i fix it?
I tried to inserted different numbers, but i always get a zero in the log.
Thanks

Column names of the query must match the setters in the target object.
Your query has a column named id but there is no setId method. You should either rename setUserId to setId or in the query give the alias user_id to id column.
From BeanPropertyRowMapper documentation:
Column values are mapped based on matching the column name as obtained from result set metadata to public setters for the corresponding properties. The names are matched either directly or by transforming a name separating the parts with underscores to the same name using "camel" case.

Related

How to don't serialize the class field in FastJson?

Today I'm using FastJson(https://github.com/alibaba/fastjson), the following is my demo code.
class User {
private final String name;
private final int age;
private final String birthday;
private String password;
public User(String name, int age, String birthday) {
this.name = name;
this.age = age;
this.birthday = birthday;
}
public void setPassword(String pwd) {
this.password = pwd;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public String getBirthday() {
return birthday;
}
public String getPassword() {
return password;
}
#Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", birthday='" + birthday + '\'' +
", password='" + password + '\'' +
'}';
}
}
It will serialize the field which has getXXX method. I do not want to serialize the password, and I will call the getPassword() to get the password value.
I do not want to rename the method getPassword and update the variable password to public.
Does anyone know how to ignore a field when serializing this class?
#JSONField(serialze=false)
public String getPassword() {
return password;
}

Cannot add a table row because of "Cannot insert explicit value for identity column in table 'Users' when IDENTITY_INSERT is set to OFF" error

I tried to save a user to the database using Spring boot and JPA but it does not work for me because of this error.
com.microsoft.sqlserver.jdbc.SQLServerException:
Cannot insert explicit value for identity column in table 'Users'
when IDENTITY_INSERT is set to OFF.
Error is clear so I've tried changing Identity insert in my database which was successful but the error still occurs. The second thing that is strange in that issue that I'm not trying to put a specific value as id to my database.
Here's the exact line that is responsible for saving data:
userService.save(new User("wikimmax","test","testmail#op.pl","test", Arrays.asList(new Role("ROLE_USER"))));
And there is my User class
import javax.persistence.*;
import java.util.Collection;
#Entity
#Table(name = "Users",uniqueConstraints = #UniqueConstraint(columnNames = "email"))
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private Long id;
private String firstName;
private String lastName;
private String email;
private String password;
#ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinTable(
name = "users_roles",
joinColumns = #JoinColumn(
name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(
name = "role_id", referencedColumnName = "id"))
private Collection<Role> roles;
public User() {
}
public User(String firstName, String lastName, String email, String password) {
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
this.password = password;
}
public User(String firstName, String lastName, String email, String password, Collection<Role> roles) {
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
this.password = password;
this.roles = roles;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Collection<Role> getRoles() {
return roles;
}
public void setRoles(Collection<Role> roles) {
this.roles = roles;
}
#Override
public String toString() {
return "User{" +
"id=" + id +
", firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", email='" + email + '\'' +
", password='" + "*********" + '\'' +
", roles=" + roles +
'}';
}
}
There Is my table properties :
Any ideas are highly appreciated
UPDATE I've manage to print SQL query that is generated by hibernate and it looks like this:
insert
into
Users
(email, firstName, lastName, password, id)
values
(?, ?, ?, ?, ?)
Add following codes :
#Id
#Column(name = "id", nullable = false)
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
Please edit question and add insert statement.
you can't insert any data in identity column, because this columns fill the automatic by SQL engine, in Insert Statement remove the id column and try it again.
Or set identity on, but its not good idea.
Allows explicit values to be inserted into the identity column of a table.
SET IDENTITY_INSERT Users ON
For Example :
USE AdventureWorks2012;
GO
-- Create tool table.
CREATE TABLE dbo.Tool(
ID INT IDENTITY NOT NULL PRIMARY KEY,
Name VARCHAR(40) NOT NULL
);
GO
-- Inserting values into products table.
INSERT INTO dbo.Tool(Name)
VALUES ('Screwdriver')
, ('Hammer')
, ('Saw')
, ('Shovel');
GO
-- Create a gap in the identity values.
DELETE dbo.Tool
WHERE Name = 'Saw';
GO
SELECT *
FROM dbo.Tool;
GO
-- Try to insert an explicit ID value of 3;
-- should return an error:
-- An explicit value for the identity column in table 'AdventureWorks2012.dbo.Tool' can only be specified when a column list is used and IDENTITY_INSERT is ON.
INSERT INTO dbo.Tool (ID, Name) VALUES (3, 'Garden shovel');
GO
-- SET IDENTITY_INSERT to ON.
SET IDENTITY_INSERT dbo.Tool ON;
GO
-- Try to insert an explicit ID value of 3.
INSERT INTO dbo.Tool (ID, Name) VALUES (3, 'Garden shovel');
GO
SELECT *
FROM dbo.Tool;
GO
-- Drop products table.
DROP TABLE dbo.Tool;
GO

Spring RestController ignoring #jsonProperty/JsonGetter/JsonSetter

I am using Springboot 2.1.2.RELEASE. I have a get request with an object as input parameter. Expecting the attributes in my class to be request parameters. My EmployeeBean has properties in java naming convention. But I need the custom names to request parameters. Tried to achieve that using #JsonProperty/ #Jsongetter/ #JsonSetter annotations but its not working. Am I missing something?
#RequestMapping(value="/api", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE )
public List<Map<String, Object>> getEmployeeData(EmployeeBean employeeBean
#Data
public class EmployeeBean implements Serializable {
private static final long serialVersionUID = -2757478480787308113L;
#JsonProperty(value="first_name")
private String firstName;
#JsonProperty(value="last_name")
private String lastName;
Try this,
private String firstName;
private String lastName;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
#JsonProperty(value="first_name")
public void setFirst_name(String firstName) {
this.firstName = firstName;
}
#JsonProperty(value="last_name")
public void setLast_name(String lastName) {
this.lastName = lastName;
}
controller
#RestController
public class JsonController {
#RequestMapping(value="/api", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE )
public List<Map<String, Object>> getEmployeeData(EmployeeBean employeeBean) {
System.out.println("employeeBean: "+employeeBean);
return null;
}
}
result:
employeeBean: EmployeeBean [firstName=firstName10, lastName=lastName20]
I've tested and it's worked
other options, using JsonCreator in constructor:
private String firstName;
private String lastName;
#JsonCreator
public EmployeeBean(#JsonProperty("first_name") String first_name, #JsonProperty("last_name") String last_name) {
this.firstName = first_name;
this.lastName = last_name;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}

Is class casting allowed?

I have 2 public classes; Person and Engineer. Engineer is inherited from Person class.
Now in main() I have a person object say
Person abc = new Person();
and I am trying to convert "abc" to Engineer i.e.
Engineer xyz = (Engineer) abc;
Question: Is this legal? My understanding is I cannot do it because "abc" might have different attributes.
Code:
public class Person {
private String firstname;
private String lastname;
private String gender;
public Person(String first, String last, String gen) {
firstname = first;
lastname = last;
gender = gen;
}
public void setFirstName(String name) {
firstname = name;
}
public void setLastName(String name) {
lastname = name;
}
public void setGender(String gen) {
gender = gen;
}
public String getFirstName() {
return firstname;
}
public String getLastName() {
return lastname;
}
public String getGender() {
return gender;
}
public toString() {
return "firstname=" + firstname + "lastname=" + lastname + "gender=" + gender;
}
public class SoftwareEngineer extends Person {
public String teamname;
public String bestlanguage;
public SoftwareEngineer(String first, String last, String gen, String team, String lang) {
firstname = first;
lastname = last;
gender = gen;
teamname = team;
bestlanguage = lang;
}
public toString() {
return "firstname=" + firstname + "lastname=" + lastname + "gender=" + gender + "teamname=" + teamname + "bestlanguage=" + bestlanguage;
}
public void main() {
SoftwareEngineer aaron = new SoftwareEngineer('Aaron','Gottlieb','M','IPSupport','SQL');
Person andy = new SoftwareEngineer('Andy','Gardner','M','IP','Java');
Person pete = new Person("Pete", "G", "M");
Person personAaron = aaron;
SoftwareEngineer sePete = (SoftwareEngineer) pete;
SoftwareEngineer seAndy = (SoftwareEngineer) andy;
pete.teamname = "FooBar";
aaron.setLastName("Brian");
}
Every engineer is a person, but not every person is an engineer. Now translate it to your OO domain. Do you think you can always cast Person to Engineer? I.e. assume that every person is an engineer?
No, but you can ask person: are you an engineer?:
if(abc instanceof Engineer) {
Engineer xyz = (Engineer) abc;
}
But you don't always have to know that. You can ask every person about name, it doesn't matter whether that person is an engineer or not:
Person p = new Engineer();
p.getFirstName();

Filter nested objects using Jackson's BeanPropertyFilter

I have the following objects:
#JsonFilter("myFilter")
public class Person {
private Name name;
private int age;
public Name getName() {return name;}
public void setName(Name name) {this.name = name;}
public int getAge() {return age;}
public void setAge(int age) {this.age = age;}
}
#JsonFilter("myFilter")
public class Name {
private String firstName;
private String lastName;
public String getFirstName() {return firstName;}
public void setFirstName(String firstName) {this.firstName = firstName;}
public String getLastName() {return lastName;}
public void setLastName(String lastName) {this.lastName = lastName;}
}
I wrote a method to marshall a Person object like this:
#Test
public void test() throws Exception {
Person person = new Person();
person.setAge(10);
Name name = new Name();
name.setFirstName("fname");
name.setLastName("lastname");
person.setName(name);
ObjectMapper mapper = new ObjectMapper();
FilterProvider filters = new SimpleFilterProvider().addFilter("myFilter",
SimpleBeanPropertyFilter.filterOutAllExcept("name.firstName"));
System.out.println(mapper.filteredWriter(filters).writeValueAsString(person));
}
What I'd like to see is JSON like this:
{"name":{"firstName":"fname"}}
Is something like that possible?
Ok, figured it out. Varargs would have made this a bit prettier, but oh well. Just hope I don't have two inner beans which have properties with the same name. I wouldn't be able to make the distinction between the two
FilterProvider filters = new SimpleFilterProvider()
.addFilter("myFilter", SimpleBeanPropertyFilter
.filterOutAllExcept(new HashSet<String>(Arrays
.asList(new String[] { "name", "firstName" }))));
There's a better way that solves problem with property name conflicts. Just add another filter to class Name ("nameFilter"):
#JsonFilter("personFilter")
public class Person {
private Name name;
private int age;
public Name getName() {return name;}
public void setName(Name name) {this.name = name;}
public int getAge() {return age;}
public void setAge(int age) {this.age = age;}
}
#JsonFilter("nameFilter")
public class Name {
private String firstName;
private String lastName;
public String getFirstName() {return firstName;}
public void setFirstName(String firstName) {this.firstName = firstName;}
public String getLastName() {return lastName;}
public void setLastName(String lastName) {this.lastName = lastName;}
}
And then add 2 filters, one for Person and one for Name:
FilterProvider filterProvider = new SimpleFilterProvider()
.addFilter("personFilter", SimpleBeanPropertyFilter.filterOutAllExcept("name"))
.addFilter("nameFilter", SimpleBeanPropertyFilter.filterOutAllExcept("firstName"));