We are five students in a team working on a project using SCRUM methode.
Our first sprint was WEB application...
Now, we are working at the second sprint which is Desktop application with JAVA.
In the first sprint(Sprint Web),we have created our database using FOS_USER Bundle, this database contains 'User' table, his sql script is(some columns):
DROP TABLE IF EXISTS `User`;
CREATE TABLE IF NOT EXISTS `User` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(180) COLLATE utf8_unicode_ci NOT NULL,
`username_canonical` varchar(180) COLLATE utf8_unicode_ci NOT NULL,
`email` varchar(180) COLLATE utf8_unicode_ci NOT NULL,
`email_canonical` varchar(180) COLLATE utf8_unicode_ci NOT NULL,
`enabled` tinyint(1) NOT NULL,
`salt` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`password` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`last_login` datetime DEFAULT NULL,
`confirmation_token` varchar(180) COLLATE utf8_unicode_ci DEFAULT NULL,
`password_requested_at` datetime DEFAULT NULL,
`roles` longtext COLLATE utf8_unicode_ci NOT NULL COMMENT '(DC2Type:array)',
PRIMARY KEY (`id`),
UNIQUE KEY `UNIQ_1D1C63B392FC23A8` (`username_canonical`),
UNIQUE KEY `UNIQ_1D1C63B3A0D96FBF` (`email_canonical`),
UNIQUE KEY `UNIQ_1D1C63B3FF631228` (`etablissement_id`),
UNIQUE KEY `UNIQ_1D1C63B3C05FB297` (`confirmation_token`)
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Now, in the sprint java, we have generated the entities from database using Netbeans tool, and we get this class(some attributs):
public class User{
private Integer id;
private String username;
private String usernameCanonical;
private String email;
private String emailCanonical;
private short enabled;
private String salt;
private String password;
private Date lastLogin;
private String confirmationToken;
private Date passwordRequestedAt;
private String roles;
}
Now, we need to persist(/get to authentificate) an User object into(/from) this database, but the problem is, the password was crypted with FOS_USER Bundle.So what is the way to decrepte/encrypte this password.
Our DAOUser is like this!?
public void ajouter(User user) {
String req = "INSERT INTO User (nom,username,email,enabled,salt,password,roles) VALUES (?,?,?,?,?,?)" ;
PreparedStatement pre;
try {
pre = connection.prepareStatement(req);
pre.setString(1, user.getUsername());
pre.setString(2, user.getEmail());
pre.setShort(3, user.getEnabled());
//Some thing wrong : exp in database {username:Zain,salt:'0Yi3LZANkpfMsnhbn2XHA00cASLCGVfWc7TJWNOjXsk')
pre.setString(4, user.getSalt());
//Some thing wrong : exp in database {username:Zain,passowrd:'qXSSYBDXWQA/ZcbPVOoBKzd5oshTkQP0Q3AeEilnh47Mcrc9uUZYDYwmRJiMKc7nRPvRx6k0eEJrc6HrrDvZtQ==')
pre.setString(5, user.getPassword());
//This Role must be unserialised(the equivalent unserialize method in php)
pre.setString(6,user.getRoles());
pre.executeUpdate();
} catch (SQLException ex) {
Logger.getLogger(EtablissementService.class.getName()).log(Level.SEVERE, null, ex);
}
}
You don't wan to decrypt password. It should be one way hash. To check validity of password, encrypt user input in the same way and check calculated hash to match the hash in the database
Related
I'm using this hibernate-types that allows hibernate to translate SQL layer data types into java classes in my springboot application, here I'm trying to add a text array field called user array.
#Entity
#Table(name = "user_update")
#Getter
#Setter
#NoArgsConstructor
#RequiredArgsConstructor
#TypeDef(name = "list-array", typeClass = ListArrayType.class)
public class UserUpdate {
#Id #NonNull private String userKey;
#Column #NonNull private String userName;
#Column #NonNull private Instant updatedAt;
#Type(type = "list-array")
#Column(columnDefinition = "text[]")
#NonNull
private List<String> userArray;
}
I can insert data into the table, but now I want to add a test and I see the following error message from the table.sql
CREATE TABLE IF NOT EXISTS user_update (
user_key VARCHAR(255) NOT NULL,
user_name VARCHAR(255) NOT NULL,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL,
user_array TEXT ARRAY NOT NULL,
PRIMARY KEY(org_key)
);
maybe it is because the test I'm running uses #DataJpaTest and for some reason it can not recognize the new text[] field ?
Error executing DDL "create table user_update (user_key varchar(255) not null, user_name varchar(255), user_array text[], updated_at timestamp, primary key (user_key))" via JDBC Statement
Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Syntax error in SQL statement "create table user_update (user_key varchar(255) not null, user_name varchar(255), user_array text[*][], updated_at timestamp, primary key (user_key))"; expected "(, ARRAY, INVISIBLE, VISIBLE, NOT, NULL, AS, DEFAULT, GENERATED, ON, NOT, NULL, DEFAULT, NULL_TO_DEFAULT, SEQUENCE, SELECTIVITY, COMMENT, CONSTRAINT, COMMENT, PRIMARY, UNIQUE, NOT, NULL, CHECK, REFERENCES, ,, )"; SQL statement:
With #DataJpaTest Spring will instruct Hibernate to create the schema and that will use the information that you provided in your annotations, but it seems this is not legal for H2.
Try using the following instead:
#Column(columnDefinition = "text array")
if a java object has a auto-increment ID field, should the Database table field should be auto-increment as well?
for example
public class Company {
private static int countID = 0;
private int companyID;
private String name;
private String email;
private String password;
private List<Coupon> couponsList;
public Company(int companyID, String name, String email, String password, List<Coupon> couponsList) {
this.companyID = companyID+=1;
this.name = name;
this.email = email;
this.password = password;
this.couponsList = couponsList;
}
you can see that the companyID field is generated automatically.
i have created this table in my SQL server
CREATE TABLE `companies` (
`ID` int NOT NULL AUTO_INCREMENT,
`NAME` varchar(200) DEFAULT NULL,
`EMAIL` varchar(200) DEFAULT NULL,
`PASSWORD` varchar(200) DEFAULT NULL,
PRIMARY KEY (`ID`)
how should I connect the Java field (commpanID) to the sql field (ID)?
No. They are different things. Auto-incremented columns in MySQL are not guaranteed to be gapless. Gaps can occur for multiple reasons. The most common are:
Concurrent transactions.
Deletion.
It sounds like you have a unique identifier in Java which is either redundant or an item of data. If the latter, then add it as an additional column.
More likely, though, you might want to reconsider your design, so there is only one auto-incremented value for a given record. I would recommend using the one in the database, because that would apply regardless of how inserts are made into the database.
It isn't compulsory to create and unique id field in the database . You can instead change the table like-->
CREATE TABLE companies (
'COMPANYID' int NOT NULL,
`NAME` varchar(200) DEFAULT NULL,
`EMAIL` varchar(200) DEFAULT NULL,
`PASSWORD` varchar(200) DEFAULT NULL,
PRIMARY KEY (`ID`)
since you are auto incrementing the same the same value twice , it will create some problems.
your ID column will be like this-->
Id|
---
2 |
---
4 |
--
6 |
--
8 |
it will increment the values twice
In my DB every question has a valid questionID (primary Key) and categoryID (foreign Key to category table).
The problem is: in the Result Set for every question both IDs are 0 instead of what's written in the DB. All other arguments are filled out correctly.
private ArrayList<Question> questions = new ArrayList<Question>();
private Connection connie;
private PreparedStatement psShowQuestions;
psShowQuestions= connie.prepareStatement("SELECT * FROM question");
ResultSet rs = psShowQuestions.executeQuery();
while (rs.next()) {
questions.add(new Question(rs.getInt("questionID"), rs.getInt("categoryID"), rs.getString("question"), rs.getString("rightAns"), rs.getString("wrong1"), rs.getString("wrong2"), rs.getString("wrong3"), rs.getString("hint")));
}
Collections.shuffle(questions);
Edit 1
Here is the original code (in the post I changed the variables from German to English):
The creation of my SQL table:
CREATE TABLE `frage` (
`frageID` int(11) NOT NULL,
`kategorieID` int(11) DEFAULT NULL,
`frage` varchar(200) NOT NULL,
`richtig` varchar(200) NOT NULL,
`falsch1` varchar(200) NOT NULL,
`falsch2` varchar(200) NOT NULL,
`falsch3` varchar(200) NOT NULL,
`hinweis` varchar(200) NOT NULL,
`anzFalsch` int(11) DEFAULT NULL,
`anzRichtig` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
private ArrayList<Frage> fragen = new ArrayList<Frage>();
private Connection connie;
private PreparedStatement psGetFragen;
ResultSet rs = psGetFragen.executeQuery();
while (rs.next()) {
fragen.add(new Frage(rs.getInt("frageID"), rs.getInt("kategorieID"), rs.getString("frage"), rs.getString("richtig"), rs.getString("falsch1"), rs.getString("falsch2"), rs.getString("falsch3"), rs.getString("hinweis")));
}
Collections.shuffle(fragen);
Most likely, there is a problem with the constructor. You might have not set questionID and categoryID in the constructor and therefore you are getting the default value of int as 0.
I'm learning about Spring Security with JdbcUserDetailsManager and I know that the default name for the MySQL table is users. The problem is that my MySQL table name is user, not users and I don't know how can I set up JdbcUserDetailsManager to work with this table.
So how can I set up this bean?
#Bean
public UserDetailsService userDetailsService() {
JdbcUserDetailsManager service = new JdbcUserDetailsManager(primaryDataSource());
return service;
}
And here is my MySQL schema:
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`password` char(80) NOT NULL,
`first_name` varchar(50) NOT NULL,
`last_name` varchar(50) NOT NULL,
`email` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=latin1;
CREATE TABLE `role` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
CREATE TABLE `users_roles` (
`user_id` int(11) NOT NULL,
`role_id` int(11) NOT NULL,
PRIMARY KEY (`user_id`,`role_id`),
KEY `FK_ROLE_idx` (`role_id`),
CONSTRAINT `FK_ROLE` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`),
CONSTRAINT `FK_USER_05` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Any feedback will be apreciated. Thank you very much!
JdbcUserDetailsManager is only useful when the role has grouping concept (Think that a role can have many permissions and an user can have many roles. We check if an user is allowed to do something by checking if he has certain permissions).
But based on your DB schema , the role does not such grouping concept. Instead , you should use much simpler JdbcDaoImpl. You have to override the following SQL according to your DB schema :
#Bean
public UserDetailsService userDetailsService() {
UserDetailsService service = new JdbcDaoImpl(primaryDataSource());
service.setUsersByUsernameQuery("select username, password , true from user where username = ? ");
service.setAuthoritiesByUsernameQuery("select user.username , role.name "
+ " from users_role "
+ " inner join role on role.id = users_role.role_id "
+ " inner join user on user.id = users_role.user_id "
+ " where user.username = ?");
return service;
}
For details about how to override these SQL , refer to the javadocs.
I am having the table called eventUserRelationMapping in that table there is two foreign key Event_id and Ringee_User_id. this eventUserRelationMapping doesn't have a separate DO class its under the UserDO class. here I am trying to get the EventUserRelationMapping for front end use. if I get the method I got the error like this
Cannot add or update a child row: a foreign key constraint fails (`ringeeapp_dev`.`event_user_relation`, CONSTRAINT `FK_EVT_RINGEE_USER_ID` FOREIGN KEY (`RINGEE_USER_ID`) REFERENCES `ringee_user` (`RINGEE_USER_ID`))
but the data inserted in that eventUserRelationMApping table
this is my geteventUserMapping()method in DAOImpl
Override
public List<UserDO> getEventUserRelationMapping(UserDO userDO)
throws UserDataException {
JdbcTemplate jd = this.getJdbctemplate();
int isNotDeleted = IRingeeConstants.IS_NOT_DELETED;
try
{
List<UserDO> userDOs = jd.query(GET_EVENT_USER_RELATION_MAPPING, new Object[] {userDO.getRingeeUserId() , isNotDeleted }, new RowMapper<UserDO>() {
#Override
public UserDO mapRow(ResultSet rs, int rowNum) throws SQLException {
UserDO userDO = new UserDO();
userDO.setEventUserId(rs.getLong(1));
userDO.setEventId(rs.getLong(2));
userDO.setRingeeUserId(rs.getLong(3));
userDO.setAttending(rs.getInt(4));
userDO.setDeleted(rs.getInt(5));
return userDO;
}
});
return userDOs;
}catch (DataAccessException dExp) {
throw new UserDataException("Error while getting eventUserRelationMapping for user " + userDO.getRingeeUserId(), dExp);
}
}
this is query for GET_EVENT_USER_RELATION_MAPPING
private static final String GET_EVENT_USER_RELATION_MAPPING = "SELECT EVENT_USER_ID, EVENT_ID, RINGEE_USER_ID, IS_ATTENDING, IS_DELETE FROM EVENT_USER_RELATION WHERE RINGEE_USER_ID = ? AND IS_DELETE = ? ";
this is the test case of getEventUserRelationMapping
#Test
#Rollback(false)
public void testgetEventUserRelationMapping() {
ArrayList<UserDO> userDOs = new ArrayList<>();
UserDO userDO = getUserDO();
userDOs.add(userDO);
UserDO userDO1 = getUserDO1();
userDOs.add(userDO1);
EventDO eventDO = getEventDO();
eventDO.setRingeeUserId(userDO.getRingeeUserId());
try {
eventDAOImpl.addEvent(eventDO);
userDAOImpl.addEventUserRelationMapping(userDOs,
eventDO.getEventId());
List<UserDO> userDOs1 = userDAOImpl
.getEventUserRelationMapping(userDO);
Assert.assertEquals(1, userDOs1);
} catch (UserDataException uExp) {
uExp.printStackTrace();
Assert.fail();
}
}
please help me to fix this issue and why it happends
THIS IS THE MYSQL QUERY FOR EVENT TABLE
CREATE TABLE `event` (
`EVENT_ID` BIGINT(20) NOT NULL,
`RINGEE_USER_ID` BIGINT(20) NOT NULL,
`TEXT` VARCHAR(45) NOT NULL,
`PLACE` VARCHAR(45) NOT NULL,
`EVENT_DATE` DATETIME NOT NULL,
`START_TIME` VARCHAR(10) NULL DEFAULT NULL,
`END_TIME` VARCHAR(10) NULL DEFAULT NULL,
`IS_DELETE` TINYINT(1) NULL DEFAULT '0',
`CREATED_DTTM` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
`MODIFIED_DTTM` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`EVENT_ID`),
INDEX `EVENT_ID` (`EVENT_ID`),
INDEX `FK_EVENT_RINGEE_USER_ID` (`RINGEE_USER_ID`),
CONSTRAINT `FK_EVENT_RINGEE_USER_ID` FOREIGN KEY (`RINGEE_USER_ID`) REFERENCES `ringee_user` (`RINGEE_USER_ID`) ON UPDATE NO ACTION ON DELETE NO ACTION
)
THIS IS FOR EVENTUSERRELATION TABLE MYSQL QUERY
CREATE TABLE `event_user_relation` (
`EVENT_USER_ID` BIGINT(20) NOT NULL DEFAULT '0',
`EVENT_ID` BIGINT(20) NULL DEFAULT NULL,
`USER_RELATION_ID` BIGINT(20) NULL DEFAULT NULL,
`IS_ATTENDING` TINYINT(4) NULL DEFAULT NULL,
`CREATED_DTTM` TIMESTAMP NULL DEFAULT NULL,
`MODIFIED_DTTM` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`EVENT_USER_ID`),
UNIQUE INDEX `EVENIT_ID_USER_RELATION_ID` (`EVENT_ID`, `USER_RELATION_ID`),
INDEX `FK_EVT_USR_USR_REL_ID` (`USER_RELATION_ID`),
CONSTRAINT `FK_EVT_USR_USR_REL_ID` FOREIGN KEY (`USER_RELATION_ID`) REFERENCES `user_relation` (`USER_RELATION_ID`),
CONSTRAINT `FK_EVT_USR_EVT_ID` FOREIGN KEY (`EVENIT_ID`) REFERENCES `event` (`EVENT_ID`)
)
First i see an error in your #Test method
Assert.assertEquals(1, userDOs1); <==> Assert.assertEquals(1, userDOs1.size());
To avoid this SQL Error you need to insert the data in your table and the in the join table
Exemple :
(tab1, tab2, tab_12)
Insert values into tab1 (commit)
Insert values into tab2 (commit)
Insert values into tab_12 (commit)