Abstract class and static in java - constructor

Hi everyone i check on the questions about using abstract class and static unfortunately i couldnt find using these two together
so here is my question;
(im little new here and i couldn't find how to instert code )
package gerekenler;
public abstract class Employee {
private int EmpId;
private String Name;
private int Age;
public Employee (int EmpId, String name, int age) {
}
}
and i want to insert static variables like workingdays (7) and bonus questions is it right to use private in abstract

First of all you it is totally ok to define private variable in your abstract class and it is only the matter of being really public, protected or private which you should decide it yourself as a programmer.
Also if you want to create a static variable in your class do it like :
private static int workingDays = 5;
or like
private static int workingDays;
static {
workingDays = 5;
}
but in your case I suggest to create an enum like
public enum WorkingDays {
Monday,
Sunday,
Tuesday,
Wednesday
Friday;
}
and use it in your class(even you can declare (private) it inside your class)

Related

How to deal with nullable reference types with System.Text.Json?

I have upgraded my project to netcore 3.0 and I am in the middle of refactoring a project to use the new nullable references types feature, but got stuck pretty quickly because of the following issue.
Lets say I consume a REST api which returns the following JSON:
{
"Name": "Volvo 240",
"Year": 1989
}
This api always returns the name/year, so they are non-nullable.
I would use this simple class for deserialization:
public class Car
{
public string Name {get; set;}
public int Year {get; set;}
}
And I would deserialize this to a Car instance using the new System.Text.Json
var car = JsonSerializer.Deserialize<Car>(json);
This all works, but when enabling nullable reference types I get a warning in the Car class that Name is declared as non-nullable but can be null. I understand why I get this since it is possible to instantiate this object without initializing the Name property.
So ideally Car should look like this:
public class Car
{
public string Name { get; }
public int Year { get; }
public Car(string name, int year)
{
Name = name;
Year = year;
}
}
But this doesn't work because System.Text.Json serializer doesn't support constructors with parameters.
So my question is: How would I declare Car so that Name is non-nullable and get it to work with System.Text.Json without getting "non-nullable" warning?`
I don't want to make it nullable because I would have to do null-checks on basically everything when enabling nullable reference types, and since the REST API in my example says that they are always provided they shouldn't be nullable.
UPDATE
System.Text.Json for .NET 5 now supports parameterized constructors, so this should not be a problem anymore.
See https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-immutability?pivots=dotnet-5-0
Old answer below
After reading the msdocs I found out how I could solve this issue.
So until System.Text.Json cannot instantiate classes with parameters in their constructor, the Car class will have to look like this:
public class Car
{
public string Name { get; set; } = default!;
public int Year { get; set; }
}
Update
If you're on net5, use the parameterized constructor support now offer as #langen points out. Else below can still be useful.
Original
Slightly alternative approach. System.Text.Json appears to have no problems using a private parameterless constructor. So you can at least do the following:
public class Car
{
public string Name { get; set; }
public int Year { get; set; }
// For System.Text.Json deserialization only
#pragma warning disable CS8618 // Non-nullable field is uninitialized.
private Car() { }
#pragma warning restore CS8618
public Car(string name, int year)
{
Name = name
?? throw new ArgumentNullException(nameof(name));
Year = year;
}
}
Benefits being:
Init of the object from your own code must be through the public ctor.
You don't need to do = null!; on each property.
Remaining downside with S.T.Json and nullable reference types:
S.T.Json still requires setters on the properties to actually set the values during deserialization. I tried with private ones and it's a no go, so we still can't get an immutable object...
Another option, for those who want to handle missing properties with meaningful exceptions:
using System;
public class Car
{
private string? name;
private int? year;
public string Name
{
get => this.name ?? throw new InvalidOperationException($"{nameof(this.Name)} was not set.");
set => this.name = value;
}
public int Year
{
get => this.year ?? throw new InvalidOperationException($"{nameof(this.Year)} was not set.");
set => this.year = value;
}
}

Mapping EXCEL Sheet to Database using JPA Hibernate

I would like to map an simple excel table to my javaEE application using hibernate. I'm really new to Databases and ORM so i would like to know if the following relations make sense and in how many Entities would make sense to split the Table.
This is the attributes contained in the Excel spreadsheet:
(Office Room Number|ComputerName|ComputerIP|Computer OS|UserFirstName|UserLastName)
Relations:
OfficeRoomNumber -- 1 : N -- Users
N users working in 1 Office?
OfficeRoomNumber -- 1 : N -- Computer
N Computers are in 1 Office ?
User -- 1:1 -- Computer
1 User got 1 Computer?
Thanks for any help and sorry for my horrible English.
Here are my 50c for modelling your domain. First, one can use an abstract base class for generic aspects, such as primary key generation:
#MappedSuperClass
public abstract class AbstractEntity {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "pk-sequence")
#SequenceGenerator(name = "pk-sequence", sequenceName = "ID_GEN", allocationSize = 1)
protected Long objectID = -1;
#Version
private int version;
public int getVersion() {
return version;
}
public long getObjectID() {
return objectID;
}
}
Note well, this can be enhanced to include other generic aspects, e.g. creation/modification date/timestamps.
Next, we introduce three domain classes/entities as follows:
#Entity
public class OfficeRoom extends AbstractEntity {
private String name;
private String roomNumer;
#ManyToMany // Maybe an employee is associated with 2 or more office places she/he might work at?
private Collection<Employee> staff;
#OneToMany(mappedBy="location")
private Collection<Computer> equipment;
// getters and setters
}
I added a comment as you can see above on the field staff. Potentially, one would like to associated two different office rooms to certain VIP staff, so you should consider this case in modelling your domain by using #ManyToMany here already.
Moving on with:
#Entity
public class Computer extends AbstractEntity {
private String name;
private String model;
private String vendor;
private String installedOS;
private String ipAddress;
#ManyToOne
private OfficeRoom location;
#OneToMany(mappedBy="machine") // Maybe a computer is associated with 2 or more employees?
private Collection<Employee> user;
// getters and setters
}
Again, consider my comment carefully. Finally,...
#Entity
public class Employee extends AbstractEntity {
private String firstName;
private String lastName;
// other staff related attributes here ...
#ManyToOne
private Computer machine;
// getters and setters
}
Note well: Use only annotations originating from the javax.persistence package, in your import statements to stay compliant with the JPA 2.x specification and remain JPA-provider neutral with your application.
Hope this helps.

Spring JPA Repository returns list of identical objects

I have a Spring JPA Repository which behaves in a strange way. To be precise, it returns a list of objects which all appear to be identical, although the underlying database query seems to be returning the correct information.
The entity class is below. It corresponds to a View in MySQL.
#Entity
#Getter
#Cacheable(false)
#Table(name="view_assignment_selector")
public class AssignmentSelectorView {
#EmbeddedId private ID id;
private int areaId;
private String name;
#Enumerated(EnumType.ORDINAL) private Preference preference;
private int assigned;
private int required;
private boolean selected;
#Embeddable #Getter
public static class ID implements Serializable {
private Integer volunteerId;
private Integer sessionId;
}
}
Here is the Repository:
public interface AssignmentSelectorViewRepository extends JpaRepository<AssignmentSelectorView, AssignmentSelectorView.ID> {
List<AssignmentSelectorView> findByIdVolunteerIdAndIdSessionId(int volunteerId, int sessionId);
}
Here is the generated query as logged by MySQL:
SELECT AREAID, ASSIGNED, NAME, PREFERENCE, REQUIRED, SELECTED, SESSIONID, VOLUNTEERID FROM view_assignment_selector WHERE ((VOLUNTEERID = 820) AND (SESSIONID = 32))
When I try the query in MySQL directly, the result is correct. But the list of AssignmentSelectorView objects is the correct size, but all entries are identical to the first.
What's going on here?
Lesson learned - by extra careful with Ids.
It's quite tricky to write #Entity classes for Views because Views don't really have Primary Keys, but the #Entity class still needs an Id.
My original Id was wrong in that the 2 columns were not unique. I needed a 3rd column. The correct Id is:
#Embeddable #Getter
public static class ID implements Serializable {
private Integer volunteerId;
private Integer sessionId;
private Integer areaId;
}
Now it works.

JPA (EBeans) Errors with Relations

First of all I am programming a webapplication with Playframework 2.2.2 which is using Ebeans.
I will start with the code because then it is easier to explain what my problem is:
This is one of my models:
#Entity
public class Topic extends Model {
#Id
private String title;
private String description;
#ManyToOne
private User createdBy;
private Integer popular;
#Formats.DateTime(pattern="dd/MM/yyyy")
private Date created;
private boolean over18;
#ManyToMany(cascade = CascadeType.REMOVE)
private List<Tag> tags;
}
The model has this method:
/**
* Return the number of opinions that exist on a specific Topic
*/
public int countOpinions() {
return Opinion.find.where().eq("topic", this).findRowCount();
}
This is my second relevant model:
#Entity
public class Opinion extends Model {
#Id
private Long opinionId;
#Constraints.Pattern("pos|neg|neut")
private String type;
#ManyToOne
private Topic topic;
#ManyToOne
private User user;
private int rating;
private String text;
private boolean reported;
#ManyToOne
private Opinion parent;
}
containing this static method
public static Model.Finder<Long, Opinion> find = new Model.Finder<Long, Opinion>(Long.class, Opinion.class);
Here we have the call in the HTML
#topics.map { topic =>
<th scope="col" id="name">#topic.getTitle()</th>
<th scope="col" id="description">#topic.getDescription()</th>
<th scope="col" id="opinions">#topic.countOpinions()</th>
}
Problem:
Ok so the countOpinions() is not working correctly. I created some testvalues, which should show the value 2 for a specific test Topic, but it shows the value 0. Im not sure how Ebeans is saving those fields with a type that I have created for myself, but afaik it should work like this.
I have tried already to override the equals methods in the Models, cause I figured it may be used, but apparently it isnt.
Thx for every help.
I tested it quickly, works fine
private FakeApplication fakeApplication;
#Before
public void setup() {
fakeApplication = fakeApplication(inMemoryDatabase());
start(fakeApplication);
}
#After
public void tearDown() {
stop(fakeApplication);
}
#Test
public void countOpinionsTest() {
// given
Topic topic = new Topic();
topic.setTitle("test");
topic.save();
Opinion opinion1 = new Opinion();
opinion1.setOpinionId((long) 1);
opinion1.save();
Opinion opinion2 = new Opinion();
opinion2.setOpinionId((long) 2);
opinion2.save();
// when
opinion1.setTopic(topic);
opinion1.update();
opinion2.setTopic(topic);
opinion2.update();
// then
assertThat(topic.countOpinions()).isEqualTo(2);
}
Do you have your ebean config set and the entity in the according package (here models)?
db.default.driver=org.h2.Driver
db.default.url="jdbc:h2:mem:play"
ebean.default="models.*"

How to store the same entity in mulitple lists in Hibernate using JPA

Im very new to Hibernate so this will probably a easy task for you guys.
As the Topic says I'm trying to reference the same entity in multiple Lists. But when I try to do so I get an exception saying: "Duplicate entry '5' for key 'military_id'".
I googled but could not find a solution to my problem.
I have an Entity called MilitaryUnitData like this:
#Entity
public class MilitaryUnitData implements IMovable{
private long Id;
//snip
#Id
#GeneratedValue(strategy=GenerationType.TABLE)
public long getId() {
return Id;
}
public void setId(long id) {
Id = id;
}
//snip
}
and a class City where I want to store my units in.
#Entity
public class CityData {
private Collection<MilitaryUnitData> military = new ArrayList<MilitaryUnitData>();
private String name;
//snip
#Id
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#OneToMany
#Column(nullable=false)
public Collection<MilitaryUnitData> getMilitary() {
return military;
}
public void setMilitary(Collection<MilitaryUnitData> military) {
this.military = military;
}
//snip
}
The problem occurs when I want to put a Unit into 2 cities at the same time.
How do I have to change the mapping to achive this?
Thx in advance.
I'm trying to reference the same entity in multiple Lists
After looking at your code, I think you mean, that the same MilitaryUnitData is used in several CityData?
IF this is correct, than the realtion ship is a M:N relation ship, and you need to use a #ManyToMany instead of an #OneToMany.