JDBC dao and inheritance - java

Let's say I have 2 classes in my model :
public class Account {
int capital;
int numero
}
public class SavingAccount extends Account{
double rate;
}
So when I have to save or retrieve an account in a database using JDBC, it works but for the binding it is OK for capital and numero but for rate I need to check the type and cast it :
if(account.getType() == AccountType.SAVINGACCOUNT) {
((SavingAccount)Account).setRate(result.getDouble("rate"));
}
Is it possible to do otherwise than that or than have 2 different methods ?

The last and just-before-implementation class is the SavingAccount. SavingAcccount contains rate's getter and setter methods. So, whenever you use getRate(), you should type cast your Account to SavingAccount, because in the heap space of SavingAccount you have getRate() method.
Because the final implementation is via SavingAccount, you also provide via TypeChecking AccountType.SAVINGACCOUNT for the correct database transactions.
When you do your executions via Account instance, it gives you polymorphic power. That's why it's important.
So, in your scenario, I don't see any other solution exists. You are doing good.

Related

Adding two numbers from the database in the Spring Service layer

I have an entity called User which holds three fields:
ID No1
1 5
2 4
Then I have a UserRepository which extends JpaRepository, thus including crud operations.
I want to be able to take value 5 and 4 and add them together.
This logic should be applied in the Service layer.
So I have a AddService interface and AddServiceImpl which implements that interface.
public interface AddService{
public void addNumbers(user1, user2);
}
public class AddServiceImpl implements AddService{
public void addNumbers(user1, user2){
List<User> user1=userRepository.findOne(1);
List<User> user2=userRepository.findOne(2);
// how do I take those specific values that are on the field No?
}
}
How do I implement this Service so that it adds those numbers?
I need to inject the repository and save a list with the data from user1 and user2 and then add them? But how do I do that?
try this code and let me know if this what you want
public Integer addNumbers(user1, user2){
List<User> user1=userRepository.findOne(1);
List<User> user2=userRepository.findOne(2);
Integer number1 = user1.getNo();
Integer number2 = user2.getNo();
return number1 + number2;
}
If the user1.getNo() or if user2.getNo() could be null please take car of this as well. I do not know in this case what you want to return.
In addition ,change the interface to return an Integer
public interface AddService{
public Integer addNumbers(user1, user2);
}
Why do you need a list of type User ? Anyway, what you should do is iterate over the list and for each User object in your list get the numbers using the getter of that field. You must have the getters and setters for all the fields on your entity class, this way you can get the value of your instance variables on your repository class.
user1.getID() and user1.getNo() without the user class it’s hard to tell. Same thing for user2. Could you provide User for us?
findOne shouldn’t have a list in return type. It should be unique.
The calls to the repository shouldn’t be in your addNumbers method because your users are in the method parameters.

How to inject property values into enum?

I'm using Spring to resolve property values from properties file, usually with #Value("${my.property}").
Now I have an enum that should have an application-wide configurable static number. For example:
public enum PersonType {
ADULT, CHILD;
private static final int MAX_CHILD = 17;
public static PersonType fromAge(int age) {
return age <= MAX_CHILD ? CHILD : ADULT;
}
}
How could I make the max child age configurable and injectable by Spring?
It's an interesting question, how one handles variables that is the same for all objects of the class and does not change during runtime, and at the same time is allowed to be configurable between executions. Since the first two prerequisites dictate that the variable should be static and final (e.g. a constant), the third really doesn't fit in, meaning that there will be no pretty way to achieve all three (reflection is needed, or one has to drop either the static or the final constraint).
Since there is no pretty solution to the way things are modeled now, I think the wisest would be to take a step back and rethink the placement of the variable: Is it necessary to keep this logic in the enum itself? What is different when changing the value of the constant, the enum itself, or something else? In what cases does this constant have to change it's value?
In your example it might be that different countries have different thresholds for what is regarded as adult, or that the threshold changes, then maybe a small service that determines which PersonType a Person has is the right way to go.
#Service
public class PersonTypeService {
#Value("${threshold.for.adulthood}")
private int thresholdForAdulthood;
public PersonType determinePersonType(final Person person) {
if (person.getAge() >= thresholdForAdulthood) {
return PersonType.ADULT;
}
return PersonType.CHILD;
}
}
In general I like to let enums only answer the "what", and leave the "how" and the "why" to domain classes and services. In the example, all the enum needs to know is the values it provides a person, why it should provide a certain value, or how it is determined, does not belong in the enum.
Moving the logic to get proper enum based on configurable age can be one of the solution
class PersonTypeFinder
{
private int maxChildAge; // set this from spring
....
public PersonType getPersonType(int age)
{
return age <= maxChildAge ? PersonType.CHILD : PersonType.ADULT;
}
}
enum PersonType
{
ADULT, CHILD;
}

Is my Java enum class correctly formatted?

From a previous question I asked on enums, I was able to understand what enums really are, but I'm still very new to them in practicing. In my lab, it unexpectedly says:
"Create class Manager which extends class SalariedEmployee and contains the following information:
-The name of the department being managed by this employee. Create an enumerated class with
the 4-8 different departments such as Payroll, Production, Accounting, Research, Marketing, etc.
-Number of employees (an integer) – a value between 1 and 100. "
Would it seem to you guys if I'm doing this correctly? :
public enum Department {
Payroll(10), Production(25), Accounting(30), Research(25), Marketing(7);
//DepartmentName(numberOfEmployees)
private int numberOfEmployees;
private Department(int numberOfEmployees) {
this.numberOfEmployees = numberOfEmployees;
}
}
Do you guys think this is valid and sufficient? Obviously the professor knows for sure what he's asking of, but from your own interpretation, am I doing this correct?
Also, If my super constructor's validation range for an int is a bigger range than the one I want the specific parameter for my subclass to have, would just issuing an if/else statement after the super() call be sufficient? For example:
public SalariedEmployee(String name, String number, double salary, double deductions) {
super(name, number);
if (salary >= 40000.00 && salary <= 160000.00) {
this.yearlySalary = salary;
} else {
this.yearlySalary = 75000.00;
BUT in the subclass I want the range to be between 40k-100k, so I did this:
public Supervisor(String name, String number, double salary, double deductions, int goals) {
super(name, number, salary, deductions);
if (salary >= 40000.00 && salary <= 100000.00) {
this.yearlySalary = salary;
} else {
this.yearlySalary = 75000.00;
}
}
Is that sufficient enough to override the super constructor's argument range/specifications? Thank you.
I doubt that the teacher intends for you to put the number of employees into the enum. Additional info provided to enums is usually data that is not subject to change. The number of employees is something that changes frequently. I believe the requirement of your instructor says that the Manager class should include a property that states how many employees are managed by the Manager, something like this:
public class Manager extends SalariedEmployee {
private Department department;
private Integer numEmployees;
...
}
Since this appears to be an assignment, I don't want to give too much more code than this. Good luck!
I think what you are asking in the second part of your question is sufficient. After calling super() in your constructor, you are free to change the values of any of the properties set by the super() method to different values. I'm not sure I fully understand what you are trying to do with the salary ranges, but I think you have given enough information to say that what you are doing is sufficient.
All you really need to put in your subclass constructor is
super(name, number, salary,deductions);
if(salary>100000.00){
this.yearlySalary=75000.00;
}
because you are aleady checking if it is between 40000 and 160000 in your superclass. Your enum looks to be correct.

EJB, JPA business method into entity

i have got uml diagram from projectant and into entity i have got method getTotalPrice()
So this is my class:
public class UOrder {
#OneToMany
private List<Product> products;
....
public BigDecimal getTotalPrice(){
BigDecimal b = new BigDecimal(0.0);
for(Product p : products){
b.add(p.getPrice());
}
return b;
}
}
It is good idea to do it like that ? logical busines into entity ?
I have got only function in uml diagram not field totalPrice or something like that so i figure out that it must be like that ...
It's more like a matter of taste. For example, if you like Domain Driven Design philosophy it's a really good idea as the total price belongs to the UOrder class.
I think isn't bad, but I preferrer like (pseudo code):
public class UOrder {
...
public BigDecimal getTotalPrice() {
return PriceUtil.getTotalPrice(products);
}
}
public class PriceUtil {
public static BigDecimal getTotalPrice(List<Product> products) {
return sum-of-products;
}
... other userful and fancy price functions ...
}
because you usually need:
to calcuate VAT or
price of other class as Product or
price in other class as UOrder
and so on.
As an alternate point of view (an active record style data mapping object is just the persisted data in a handy form - a value object), here's what I think:
Given that you've said that the method is business logic, and given the well known domain that #Anton talks about - it's a bad idea. If you hadn't said it was business logic, I'd have questioned why you cared about that total in your application.
As an experiment, consider re-naming your mapped class UOrderData, treat it as a value object, and have a UOrder class that implements the business logic at application level.

JPA 2.0 persisting property with no setter

I'm using JPA 2.0, more precisely Eclipselink. Here's my problem:
I have an entity that has a property like "isPaid". that property is the result of some calculations the entity performs with some of its other fields. since this is derived from other fields, the property does not have a setter method.
As an example, the getter is something like this:
public boolean isPaid() {
return this.totalAmount - this.amountPaid == 0;
}
that's just an example. The thing is, I want this property to be calculated and persisted, so i can do a jpql query like:
SELECT d FROM Debt d WHERE d.isPaid = true
Is this possible? Is there any workaround for this?.
I don't want to retrieve all entities to call this method and then filter those that return true.
Here are a couple of options:
1) Create a jpql query that directly does what you need:
select d from Debt d where (d.totalAmount - d.amountPaid) = 0
The benefits of the approach is that it is simple and will always work. The downside is that your query has to understand how the paid logic was calculated.
2) Create a persisted paid value that stores the calculated value:
#Basic
private boolean paid;
public boolean isPaid() {
return this.paid;
}
private void updateCalculations() {
this.paid = (this.totalAmount - this.amountPaid == 0);
}
// using int as example here
public void setTotalAmount(int totalAmount) {
this.totalAmount = totalAmount;
updateCalculations();
}
public void setAmountPaid(int amountPaid) {
this.amountPaid = amountPaid;
updateCalculations();
}
The benefit of this approach is that you will be able to create a jpql query that directly checks for the boolean value, i.e.,
select d from Debt d where d.paid = true;
Obviously, the downside to the approach is that you need to make sure to recalculate the value anytime you update the values. However, this can be alleviated if you only calculate it on access. Meaning that in your isPaid() method, you calculate the value, assign it to the paid attribute and then return the value. If you decide to go with this approach, you will need to add a #PrePersist and #PreUpdate method that performs the paid calculation and updates the paid attribute prior to the bean being persisted to the datastore (makes sure that the paid value is always covered.
If you use JPA annotations on your attributes themselves, you can have a getter without a setter and still be able to correctly retrieve and store the values in the database.
Seen this: Mapping calculated properties with JPA ?
Basically you need a setter one way or the other in order to make JPA happy.

Categories

Resources