how do I create user defined roles and then how do I use them to code my JSPS to present them according to the user role type in a spring MVC web application
If I understand you correctly.
Use jstl.
<%# taglib prefix = "c" uri = "http://java.sun.com/jsp/jstl/core" %>
With the " if " condition, you can create different menu calls for different users.
JSTL - Core Tag
<c:if test="${example != null}">
<center>
${example}
</center>
</c:if>
Below are the steps to do that.
1.Create a role entity.
2.Create a user entity.
3.Establish relationship between both tables like (OneToMany or #ManyToMany based on your requirement)
4.Insert a role in table.
5.create a user by assigning the role to the user.
6.Once DB relationships are done then inside JSP page you can get role and put a condition to check that and you are done.
Code for step 1 :
#Entity
public class Role implements GrantedAuthority {
private static final long serialVersionUID = 1L;
#NotNull
private String roleName;
private String description;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private Long id;
//getters and setters and other fields like roleName,description etc.
}
Step 2 &3:
#Entity
public class User extends BaseEntity implements UserDetails, Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private Long id;
#Column(unique = true)
private String userId;
#ManyToOne
private Role role;
//getters and setters and other fields like password,etc.
}
Step 6 :
<sec:authorize ifAnyGranted="ROLE_ADMIN" >
write code here which only ADMIN can see
</sec:authorize>
Related
I'm new to Spring, I fear this question may be duplicate, as there are numerous ways to do get resource from database to drop-down which I don't understand, so I'm asking if anyone can help me by fixing my code or with their own code which matches with mine as it'll be easy for me to learn.
My POJO
#Entity
#Table(name = "emp69")
public class Emp {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
private String designation;
....Constructor with name & designation field...
......getters method and setters method.....
My Repository
public interface EmpRepository extends JpaRepository<Employee, Integer> {
#Modifying
#Query(
value = "select designation from employee",
nativeQuery = true
)
List<String> designation();
}
My Data Access Object
#Service
public class EmployeeDao {
#Autowired
private EmpRepository repo;
#Transactional
public List<String> desig() {
return repo.designation();
}
}
My Controller
#Controller
public class EmployeeController {
#Autowired
EmployeeDao dao;
#RequestMapping("/empform")
public String showform(Model m) {
List<String> designation= dao.designation();
m.addAttribute("designation", designation);
return "empform";
}
}
My JSP page
<select>
<c:forEach var="dd" items="${designation}">
<option><c:set var="dd.designation">${dd.designation }</c:set></option>
</c:forEach>
</select>
seems everything fine to me but when I execute, it gives
Property [designation] not found on type [java.lang.String]
error.
And on STS console
javax.el.PropertyNotFoundException: Property [designation] not found on type [java.lang.String]
Your Controller, Service & Repository part are correct but it seems like you haven't studied JSP well. I'll suggest you to take a step back from a big framework and individually learn each of its aspects first like JSP, JSTL, etc. Following this path will lead you to understanding of big frameworks and everything will be more clear.
Anyhow here's your answer..
<select>
<c:forEach var="dd" items="${designation}">
<option><c:set var="d" value="${dd}" /><c:out value="${d }"/></option>
</c:forEach>
</select>
just replace this part in your code..
Hope it helps
This is a REST XML service. On Save, the foreign key value in child table is empty.
The #Id's are using sequence and it works fine. Im not added the sequence generator code here.
//Main Entity
------------
#Entity
#Table(name="REQUEST")
public class MsaDisabScreenRequest implements Serializable {
#Id
#Column(name="REQUEST_ID")
private long requestId; //sequence
#OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.LAZY, mappedBy="msaDisabScreenRequest")
private Set<ReqDetail> disabilities;
}
Child Entity
#Entity
#Table(name="REQ_DETAILS")
public class ReqDetail implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name="MAP_ID")
private long mapId; //sequence
#Column(name="TYPE_ID")
private long disabilityTypeId;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name="REQUEST_ID")
privateRequest msaDisabScreenRequest;
}
This is the dto that I'm using to map.
//Main Dto
#XmlRootElement(name="DisabilityRequest")
#XmlAccessorType(XmlAccessType.FIELD)
public class MsaDisabScreenRequestDto implements Serializable {
private static final long serialVersionUID = 1L;
private long requestId;
#NotNull
private Set<DetailDto> disabilities;
}
//Child Dto
#XmlRootElement(name="disabilities")
#XmlAccessorType(XmlAccessType.FIELD)
public class MsaDisabScreenReqDetailDto implements Serializable {
private static final long serialVersionUID = 1L;
private long mapId;
private long disabilityTypeId;
#XmlTransient
private RequestDto msaDisabScreenRequest;
}
This is the controller
#RequestMapping(value = ApiPath.REQUEST, method = RequestMethod.POST, produces = { "application/xml"})
public #ResponseBody ResultDecorator saveScreeningRequest(#Valid #RequestBody RequestDto requestDto) throws Exception {
.
.
.
.
}
save code which is using jpa repository to persist.
Implementation code only added the code releavant to save
#Autowired
private OrikaBeanMapper mapper;
.
.
.
.
.
.
.
// mapping
Request request = mapper.map(requestDto,Request.class);
Request Res = msaRepository.save(request);
This is the request payload I'm sending
<?xml version="1.0" encoding="UTF-8" ?>
<DisabilityRequest>
<disabilities>
<disabilityTypeId>9</disabilityTypeId>
</disabilities>
</DisabilityRequest>
Here the requestId is added as empty REQ_DETAILS table. All other entries passed are persisted.
Let me know if you need any further details.
When fetch type is LAZY, the data set are empty. You can use Fetch type EAGER but its expensive
THis is the main entity class, which is having an embeddedId
public class LabResHivMutation implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
private LabResHivMutationPK id;
private String comments;
#Column(name="MUTATION_TYPE_ID")
private BigDecimal mutationTypeId;
#Column(name="VALUE")
private String value;
}
This is the embeddable key
#Embeddable
public class LabResHivMutationPK implements Serializable {
//default serial version id, required for serializable classes.
private static final long serialVersionUID = 1L;
#Column(name="TO_INST")
private Long toInst;
#Column(name="REL_INVSTID")
private long relInvstid;
#Column(name="MUTATION_ID")
private long mutationId;
}
Is there any delete methos available in spring data Jpa to delete based on only two of the embaddable key(toInst,relInvstid).
I still can write a JPQL query to delete it. My question is there any method available for this.
like deleteById ?
Yes there is, repo.deleteByIdToInstAndIdRelInvstid(toInst,relInnvstid)
As you see you have to specify deleteByIdToInst , this is how you reference a field of an embedded ID , the same as you would reference a field of a foreign relation. Here Id matches your field naming
#EmbeddedId
private LabResHivMutationPK id;
There are two ways to delete an entity: either using its own "JPA Repository derived delete method" long deleteByFirstIdAndSecondId(long firstId , secondId)
In your service you can simply call it : repository.deleteByFirstIdAndSecondId(long firstId , secondId)
Another way is through the parent entity by excluding the child entity (or entities depends on the relation type).
User underscore '_' when entity will have multiple keys with using #Embedded keys.
example :repository.deleteByid_toInst();
The domain model is
An industry has many companies
A company belongs to an industry
So I have my entity classes:
#Entity
public class Industry {
#Id #GeneratedValue
private Long id;
private String name;
#OneToMany(targetEntity = Company.class, fetch = FetchType.LAZY, mappedBy = "industry")
private Collection<Company> companies = new ArrayList<>(0);
// Getters and setters
}
and
#Entity
public class Company {
#Id #GeneratedValue
private Long id;
private String name;
#ManyToOne(cascade = CascadeType.DETACH, fetch = FetchType.EAGER, optional = false)
private Industry industry;
// Getters and setters
}
My controller:
#RestController
#RequestMapping("/companies")
public class CompaniesController extends ControllerBase {
#RequestMapping(method = RequestMethod.POST)
public Company create(#RequestBody Company company) {
company.getIndustry(); // returns null
// ...
}
}
When I send request POST /companies with request body
{
"name": "Walmart",
"industry": {
"id": 1
}
}
I found that company.getIndustry() always returns null. How can I make the controller accept nested entities?
Entities are session based. They usually work on basis of Lazy loading I.e only the first level is loaded and other attributes are loaded on Demand. You cannot pass it from one layer to other. (service to controller)
The correct way to do it. Have a Value object (a simple class) n the controller. Use it between front end and back end. Send the same value object to service. And use the entity only between Service and DAo layer
public class CompanyVO{
private Long id;
private String name;
private IndustryVO industryVO; // create similar class
// Getters and setters
}
#RestController
#RequestMapping("/companies")
public class CompaniesController extends ControllerBase {
#RequestMapping(method = RequestMethod.POST)
public Company create(#RequestBody CompanyVO companyVO) {
companyVO.getIndustry(); // returns null
// ...
}
}
This may be because you need another Spring message converter instead of the default one. Just add jackson to your pom.xml and Spring will use MappingJackson2HttpMessageConverter.
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.5</version>
</dependency>
In my Spring app i have Two entity:
#Entity
public class Category {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
....
#OneToOne
#Cascade({CascadeType.ALL})
#JoinColumn(name="page_id")
private Page page;
#OneToMany(fetch=FetchType.LAZY, mappedBy="category")
private List<Shop> shop;
..getters and setters
}
And
#Entity
public class Shop {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
....
#OneToOne(mappedBy="shop")
private Settings settings;
#ManyToOne
#Cascade({CascadeType.SAVE_UPDATE})
#JoinColumn(name = "category_id")
private Category category;
#OneToOne
#Cascade({CascadeType.ALL})
#JoinColumn(name = "page_id")
private Page page;
...getters and setters
}
And in my test jUnit i added some category and some shop with this category, when i want to access to list of shops current category i have a error
java.lang.NullPointerException ....
My test:
#ContextConfiguration(locations = {
"classpath:security-context.xml",
"classpath:dao-context.xml"
})
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
#TransactionConfiguration(transactionManager="transactionManager", defaultRollback=false)
#Transactional
public class CategoryTest {
Shop shop1 = new Shop(....);
Shop shop1 = new Shop(....);
Category category1 = new Category(....);
Category category2 = new Category(....);
#Test
public void someTest(){
shop1.setCategory(category1);
shop2.setCategory(category2);
shopService.add(shop1);
shopService.add(shop2);
assertEquals(2, shopService.getAllShop().size());
assertEquals(2, categoryService.getAllShop().size());
//IN THIS LINE I HAVE A ERROR
assertEquals(1, categoryService.getCategory(category1.getId()).getShop().size());
}
}
For access to lazy atribute i added to my web.xml filtr: org.springframework.orm.hibernate3.support.OpenSessionInViewFilter This working properly in front app not in jUnit test.
Which point I make an error?
The lazy loading only takes place whist inside a transaction, when the session is open. So you get null in the test method unless you initialize the lazy loaded collection beforehand.
Another similar question