Hi have a strange error.
I have always used the instanceof for see the specific object of an abstract class,
But not run and I don't understand why.
I work for a Java project created with spring boot (1.5.16.RELEASE), is a maven project, with JAVA8 and for my MySql db use querydsl-jpa.
I have an abstractClass for define the user for login.A single user can have only one role, and I have create an AbstractUser class:
#Entity
#Audited
#Data
#DiscriminatorColumn(name="dType", discriminatorType = DiscriminatorType.STRING)
public abstract class AbstractUser extends AbstractDomainAudit{
private static final long serialVersionUID = 7060362023055663647L;
#Column(updatable=false, insertable=false)
private String dType;
#JsonIgnore
private String password;
#JsonIgnore
#Transient
private String newPassword;
#JsonIgnore
#Transient
private String confirmNewPassword;
#Column(nullable=false,unique=true, updatable=false)
private String userName;
private boolean able;
private String name;
#Email
private String email;
}
One of my extender classes is the follow:
#Entity
#Audited
#Data
#DiscriminatorValue(value = "Admin")
public class Administrators extends AbstractUser implements Serializable{
/**
*
*/
private static final long serialVersionUID = 7061564146290031007L;
}
But when in my controller, I try to define the instanceof, not run:
#GetMapping(value="/{id}", params="form")
public String updateForm(#PathVariable(value="id") final Long id, final Model uiModel) {
AbstractUser user = userService.findById(id);
if(user instanceof Administrators) {
Administrators u = (Administrators) user;
uiModel.addAttribute(USER, u);
}else if (user instanceof Commercial){
Commercial ut = (Commercial) user;
uiModel.addAttribute(USER, ut);
}
return UPDATE_PAGE;
}
My condition is ignored.
And I don't understand why. Can anyone help me?
JPA-annotated Classes might be proxied at runtime. Try logging your instance's class
user.getClass().getCanonicalName()
Have a look here for example: JPA, inheritance and instanceof
Related
i use querydsl, hibernate
i want select data by Dto in Dto list but not working
here is my code
#Data
#Entity
public class Team {
#Id
#GeneratedValue
private Long id;
private String name;
#OneToMany(mappedBy = "team")
private List<Member> members = new ArrayList<>();
}
#Entity
#Setter
public class Member {
#Id
#GeneratedValue
private Long id;
private String name;
#ManyToOne
#JoinColumn(name = "team_id")
private Team team;
}
#Setter
public class TeamDto {
private Long id;
private String name;
private List<MemberDto> members = new ArrayList<>();
}
#Setter
public class MemberDto {
private Long id;
private String name;
}
test
#BeforeEach
void setup() {
queryFactory = new JPAQueryFactory(em);
Team team = new Team();
team.setName("teamA");
em.persist(team);
Member member = new Member("memberA");
member.setTeam(team);
em.persist(member);
Member member2 = new Member("memberB");
member2.setTeam(team);
em.persist(member2);
em.flush();
em.clear();
}
#Test
void t1() {
TeamDto teamDto = queryFactory
.select(Projections.fields(
TeamDto.class,
team.id,
team.name,
Projections.fields(
MemberDto.class,
member.id,
member.name
).as("members")
))
.from(team)
.fetchOne();
System.out.println("teamDto = " + teamDto);
}
error log is = java.lang.IllegalArgumentException: com.blog.querydsltest.domain.dto.MemberDto is not compatible with java.util.List
what is problem?? is impossible bring data by List dto??
i try to change Projections.fields to bean, construct, ... but not working
how can i do ?
Multi level aggregations are currently not supported by QueryDSL. There are also no concrete plans to support it as of now.
For a DTO solution that can fetch associations with it, I recommend you to have a look at Blaze-Persistence Entity Views. With Entity Views the code for your DTO would look something like the following:
#EntityView(Team.class)
public interface TeamDto {
#IdMapping public Long getId();
#Mapping("name") public String getName();
#Mapping("members") public List<MemberDTO> getMembers();
}
If members is not an association on your TeamEntity, you can map it through a #MappingCorrelated binding.
Disclaimer: I am a contributor for Hibernate, QueryDSL and Blaze-Persistence.
I use h2 in memory db and I don't want to create duplicate locations in my DataBase. Only when I use createItem and input location column id manualy it write it to the same location. Otherwise even if the country city gps coordinates are the same app write it to other location with it's id.
I tried to understand but It's not working
I got these entities.
#Entity
#Table(name = "item_System_items")
public class Item {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String title;
private String description;
private BigDecimal price;
private Integer stock;
#ManyToOne
#JoinColumn(name = "location_id")
#Cascade(value={org.hibernate.annotations.CascadeType.ALL})
private Location location;
And
#Entity
#Table(name = "item_System_locations")
public class Location {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String country;
private String city;
private String street;
private String gpsCoordinates;
SETTERS AND GETTERS IS THERE I JUST NOT POST THEM HERE
Controller
#RestController
#RequestMapping("/items")
public class ItemsController {
#Autowired
private ItemsService service;
#PostMapping
#ResponseStatus(value=HttpStatus.CREATED)
public int createItem(#RequestBody Item item) {
return service.createItem(item);
}
Service
#Service
#Transactional
public class ItemsService {
#Autowired
private ItemJPARepository repository;
public int createItem(Item item) {
return repository.save(item).getId();
}
I expect after re-coding app doesn't make new location if the column values are the same.
Thank you people!
If you really help me I would be so happy!
There is nothing in your Entity definitions to tell the ORM about the constraint you want.
You can add #UniqueConstraint to the #Table in your Location entity and specify which column(s) must all be in a unique combination (example given in the linked documentation):
#Table(
name="EMPLOYEE",
uniqueConstraints=
#UniqueConstraint(columnNames={"EMP_ID", "EMP_NAME"})
)
This will add a check in the database, if the ORM is managing your database schema, which will throw an exception when violated.
I am doing a project for my studies using Spring, Maven, Tomcat, mySQL. I would like to create a website where users can login and update their settings and based on these settings they generate stuff.
At the moment the login is working fine and new users can be registered and saved to the database. Now I created a new entity and made a one to one reletaionship between the two tables - one is the table of the login details like password and username and the other one contains the settings of this user. The issue I am facing:
I have some textfield and combobox in the UI with vaadin - I populate the fields and click save
A binder passes these settings to a service that saves the object
It gets the currently logged in user and loads it from the database
When SQL tries to save the objects it throws error:
Caused by: java.sql.SQLException: Field 'user_login_id' doesn't have a
default value
Here are the entities:
#Entity
#Table(name = "USERLOGIN")
public class UserLogin implements UserDetails {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name = "id")
private Integer id;
#Column(name = "username")
private String username;
#Column(name = "password")
private String password;
#OneToOne(mappedBy = "userlogin")
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
**Other getters and setters**
}
#Entity
#Table(name = "USER")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue
private Integer id;
#Column(name = "meal")
private Integer meal;
#OneToOne
#JoinColumn(name = "userlogin_id")
private UserLogin userlogin;
public UserLogin getUserLogin() {
return userlogin;
}
public void setUserLogin(UserLogin userLogin) {
this.userlogin = userLogin;
userLogin.setUser(this);
**Other getters and setters**
}
The service that saves the settings:
#Service
public class AddUserServiceImpl implements AddUserService{
#Autowired
private UserRepository userRepository;
#Autowired
private CurrentUserService currentUserService;
public void saveUser(User userDAO) {
User user = new User();
user.setMeal(userDAO.getMeal());
user.setUserLogin(currentUserService.getCurrentUser());
userRepository.save(user);
}
}
The repository extends the JPArepository:
#Repository
public interface UserRepository extends JpaRepository<User, Integer>{
}
And finally the service and the repository that loads the currently logged in user:
#Service
public class CurrentUserServiceImpl implements CurrentUserService {
#Autowired
UserLoginRepository userLoginRepository;
public String getCurrentUsername() {
return SecurityContextHolder.getContext().getAuthentication().getName();
}
public UserLogin getCurrentUser() {
return userLoginRepository.findByUserName(getCurrentUsername());
}
}
#Repository
public interface UserLoginRepository extends JpaRepository<UserLogin,
Integer> {
#Query("select u from UserLogin u where u.username=:username")
UserLogin findByUserName( #Param("username") String username);
}
Any help would be appreciated I am really new to this topic. So the main goal is that I want to have a table that stores properties for the currently logged in user - these settings should be able to be updated any time. Is there any best practice for this?
Thank you!
Spring LdapRepository save() method throws exception when I'm trying to update an existing object in LDAP database.
org.apache.directory.api.ldap.model.exception.LdapEntryAlreadyExistsException: ERR_250_ENTRY_ALREADY_EXISTS
What method should I use to update existing ldap objects?
Person class:
#Entry(objectClasses = { "inetOrgPerson", "organizationalPerson", "person", "top" })
public class Person implements Serializable {
public Person() {
}
#Id
private Name dn;
#Attribute(name = "cn")
#DnAttribute(value = "cn")
#JsonProperty("cn")
private String fullName;
#Attribute(name = "uid")
private String uid;
private String mail;
#Attribute(name = "sn")
private String surname;
//setters and getters
}
Person repo interface:
public interface PersonRepo extends LdapRepository<Person> {
}
That's how I'm updating person:
personRepo.save(person);
Default implementation for Spring LDAP repositories is SimpleLdapRepository, that checks the property annotated with #Id to determine if the objects is new - and perform create, or old - and perform update.
I'm guessing that Person.dn is null when you're trying to perform update.
You also can take the control over this by implementing org.springframework.data.domain.Persistable and place your logic in the isNew() method.
See the implementation details.
So I have really been struggling to figure this out but there doesn't seem to be good documentation on how to do this. I have an entity RepairMan with a list of Skill entities. I need a query that can return a List<RepairMan> whose list of skills contain all the skill id's. Here is what the entities look like:
#Entity
#Table(name = "REPAIRMAN")
public class RepairMan implements Serializable
{
private static final long serialVersionUID = 8151638047721448259L;
#SequenceGenerator(name="REPAIRMAN_SEQ", sequenceName="REPAIRMAN_SEQ", allocationSize=1, initialValue=100)
#Id #GeneratedValue(generator="REPAIRMAN_SEQ")
private Long id;
#OneToMany
#JoinTable(name="REPAIRMAN_SKILLS", joinColumns=#JoinColumn(name="REPAIRMAN_ID"), inverseJoinColumns=#JoinColumn(name="SKILL_ID"))
private List<Skill> skills;
....
}
#Entity
#Table(name = "SKILL")
public abstract class Skill implements Serializable
{
private static final long serialVersionUID = -5272849377636005084L;
#SequenceGenerator(name="SKILL_SEQ_GEN", sequenceName="SKILL_SEQ", allocationSize=1, initialValue=100)
#Id
#GeneratedValue(generator="SKILL_SEQ_GEN", strategy=GenerationType.SEQUENCE)
private Long id;
#Column(name="NAME")
private String name;
#Column(name="DESCRIPTION")
private String description;
...
}
And here's the desired signature and what I have been able to work out in my mind:
public class RepairManRepositoryImpl extends QueryDslRepositorySupport implements RepairManRepositoryCustom
{
public CompanyInspectorRepositoryImpl()
{
super(RepairMan.class);
}
#Override
public List<RepairMan> getRepairMenByRequiredSkills(List<Long> skillIds)
{
PathBuilder<RepairMan> repairManPath = new PathBuilder<>(RepairMan.class, "repairman");
PathBuilder repairManSkillsPath = repairManPath.get("skills"); // probably wrong
BooleanBuilder hasAllSkills = new BooleanBuilder();
for (Long skillId : skillIds)
{
hasAllSkills.and(repairManSkillsPath.getNumber("id", Long.class).eq(skillId));
}
JPAQuery query = new JPAQuery(getEntityManager())
.from(repairManPath)
//need to join the repairManSkills somehow
.where(hasAllSkills);
return query.list(repairManPath);
}
}
I know this doesn't exactly work, plus I understand it would be easier to use the Qclasses but for compatibility reasons I can't do Qclasses.