How to sort HashSet by HashCode() - sorting

HashSet<Employee> hs= new HashSet<Employee>();
Employee e1 = new Employee("Tatha",20,6000);
Employee e2 = new Employee("Amar",30,9000);
Employee e3 = new Employee("Aziz",25,15000);
Employee e4 = new Employee("Tatha",20,6000);
hs.add(e1);
hs.add(e2);
hs.add(e3);
hs.add(e4);
how to sort by EmpID? in hashCode() method

Related

Parameter specified as non-null is null exception with Room Relations

I've defined a model that represents a meeting, with a menu and a workout plan.
The menu has a list of courses, each of which has a list of meals, and the workout plan has a list of exercises.
[
{
"menu": {
"courses": [
{
"meals": [
{
...
}
],
}
],
},
"workoutPlan": {
"exercises": [
{
...
},
]
},
}
]
in that way:
PopulatedMeeting.kt
data class PopulatedMeeting(
#Embedded val meeting: MeetingEntity,
#Relation(
parentColumn = "menuId",
entityColumn = "id",
entity = MenuEntity::class
)
val menu: PopulatedMenu,
#Relation(
parentColumn = "workoutPlanId",
entityColumn = "id",
entity = WorkoutPlanEntity::class
)
val workoutPlan: PopulatedWorkoutPlan
)
PopulatedMenu.kt
data class PopulatedMenu(
#Embedded
val menu: MenuEntity,
#Relation(
parentColumn = "id",
entityColumn = "id",
associateBy = Junction(
value = MenuCourseCrossRef::class,
parentColumn = "menu_id",
entityColumn = "course_id"
),
entity = CourseEntity::class
)
val courses: List<PopulatedCourse>
)
When I run the app, I'm getting this execption:
java.lang.NullPointerException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkNotNullParameter, parameter menu
The reason is most likely that you have a Meeting that does not reference a Menu.
Consider the following data which results in:-
Caused by: java.lang.NullPointerException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkNotNullParameter, parameter menu
at a.a.so74866469kotlinroomrelations.PopulatedMeeting.<init>(Unknown Source:7)
at a.a.so74866469kotlinroomrelations.AllDao_Impl.getAllPopulatedMeetings(AllDao_Impl.java:382)
at a.a.so74866469kotlinroomrelations.MainActivity.onCreate(MainActivity.kt:34)
based upon what can easily be ascertained from your code.
The database, via App inspection has:-
The MeetingEntity table populated with:-
Note the menuid value of 100
The MenuEntity table populated with:-
i.e. there is no row with an id of 100
Hence the menu will be null when retrieving a PopulatedMeeting.
The following activity code was used to create the above:-
class MainActivity : AppCompatActivity() {
lateinit var db: TheDatabase
lateinit var dao: AllDao
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
db = TheDatabase.getInstance(this)
dao = db.getALlDao()
val pm = dao.getAllPopulatedMeetings()
val c1 = dao.insert(CourseEntity(courseName = "C1"))
val c2 = dao.insert(CourseEntity(courseName = "C2"))
val c3 = dao.insert(CourseEntity(courseName = "C3"))
val w1 = dao.insert(WorkoutPlanEntity(workoutPlanName = "W1"))
val w2 = dao.insert(WorkoutPlanEntity(workoutPlanName = "W2"))
val w3 = dao.insert(WorkoutPlanEntity(workoutPlanName = "W3"))
val m1 = dao.insert(MenuEntity( workoutPlanId = w1, menuName = "M1"))
val m2 = dao.insert(MenuEntity(workoutPlanId = w2, menuName = "M2"))
val m3 = dao.insert(MenuEntity(workoutPlanId = w3, menuName = "M3"))
dao.insert(MenuCourseCrossRef(menu_id = m1, course_id = c1))
dao.insert(MenuCourseCrossRef(menu_id = m1, course_id = c2))
dao.insert(MenuCourseCrossRef(menu_id = m2, course_id = c2))
dao.insert(MenuCourseCrossRef(menu_id = m2, course_id = c3))
dao.insert(MenuCourseCrossRef(menu_id = m3, course_id = c3))
val meet1 = dao.insert(MeetingEntity(menuId = m1, meetingName = "MEET1"))
val meet2 = dao.insert(MeetingEntity(menuId = m2, meetingName = "MEET2"))
logPopulatedMeetings(dao.getAllPopulatedMeetings(),"STG1")
val meet3 = dao.insert(MeetingEntity(menuId = 100, meetingName = "MEET3"))
logPopulatedMeetings(dao.getAllPopulatedMeetings(),"STG2")
}
fun logPopulatedMeetings(populatedMeetingsList: List<PopulatedMeeting>, suffix: String) {
val TAG = "DBINFO_$suffix"
val sb = StringBuilder()
for (pm in populatedMeetingsList) {
sb.clear()
for (c in pm.menu.courses) {
sb.append("\n\t${c.courseName}")
}
Log.d(TAG,"Meeting is ${pm.meeting.meetingName} Menu is ${pm.menu.menu.menuName} it has ${pm.menu.courses.size} courses. They are:-$sb")
}
}
}
The log when running the above includes:-
2022-12-21 10:37:37.520 D/DBINFO_STG1: Meeting is MEET1 Menu is M1 it has 2 courses. They are:-
C1
C2
2022-12-21 10:37:37.520 D/DBINFO_STG1: Meeting is MEET2 Menu is M2 it has 2 courses. They are:-
C2
C3
2022-12-21 10:37:37.530 D/AndroidRuntime: Shutting down VM
2022-12-21 10:37:37.534 E/AndroidRuntime: FATAL EXCEPTION: main
Process: a.a.so74866469kotlinroomrelations, PID: 19356
java.lang.RuntimeException: Unable to start activity ComponentInfo{a.a.so74866469kotlinroomrelations/a.a.so74866469kotlinroomrelations.MainActivity}: java.lang.NullPointerException: Parameter specified as non-null
i.e. the PopulatedMeetings with a valid reference to a Menu are fine and utilise your PopulatedMeeting and PopulatedMenu (albeit it that the related Workoutplan was excluded for convenience/brevity).
You may wish to consider enforcing Referential Integrity (e.g. so that the menu_id cannot be a value that does not reference an actual menu).
To enforce referential integrity you can setup Foreign Keys e.g. if the following were coded:-
#Entity(
foreignKeys = [
ForeignKey(
MenuEntity::class,
parentColumns = ["id"],
childColumns = ["menuId"],
onDelete = ForeignKey.CASCADE,
onUpdate = ForeignKey.CASCADE
)
]
)
data class MeetingEntity(
#PrimaryKey
val id: Long?=null,
val menuId: Long,
val meetingName: String
)
Then the code above would instead fail with the following in the log (and more importantly when trying to insert the errant reference):-
2022-12-21 10:48:08.427 D/DBINFO_STG1: Meeting is MEET1 Menu is M1 it has 2 courses. They are:-
C1
C2
2022-12-21 10:48:08.427 D/DBINFO_STG1: Meeting is MEET2 Menu is M2 it has 2 courses. They are:-
C2
C3
2022-12-21 10:48:08.430 D/AndroidRuntime: Shutting down VM
2022-12-21 10:48:08.433 E/AndroidRuntime: FATAL EXCEPTION: main
Process: a.a.so74866469kotlinroomrelations, PID: 19822
java.lang.RuntimeException: Unable to start activity ComponentInfo{a.a.so74866469kotlinroomrelations/a.a.so74866469kotlinroomrelations.MainActivity}: android.database.sqlite.SQLiteConstraintException: FOREIGN KEY constraint failed (code 787 SQLITE_CONSTRAINT_FOREIGNKEY)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3449)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: android.database.sqlite.SQLiteConstraintException: FOREIGN KEY constraint failed (code 787 SQLITE_CONSTRAINT_FOREIGNKEY)
at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:938)
at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:790)
at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:88)
at androidx.sqlite.db.framework.FrameworkSQLiteStatement.executeInsert(FrameworkSQLiteStatement.kt:42)
at androidx.room.EntityInsertionAdapter.insertAndReturnId(EntityInsertionAdapter.kt:102)
at a.a.so74866469kotlinroomrelations.AllDao_Impl.insert(AllDao_Impl.java:139)
at a.a.so74866469kotlinroomrelations.MainActivity.onCreate(MainActivity.kt:38)
Note that you would have to have code that handles the Foreign Key conflict rather than just failing. e.g.
:-
fun insertIgnoringFKConflict(meetingEntity: MeetingEntity): Long {
var rv = -1L;
try {
rv = insert(meetingEntity)
} catch (e: SQLiteConstraintException) {
rv = -1
}
finally {
return rv
}
}
In which case replacing the insert with insertIgnoringFKConflict for the 3 Meetings results in no failure and the log including:-
2022-12-21 10:59:12.898 D/DBINFO_STG1: Meeting is MEET1 Menu is M1 it has 2 courses. They are:-
C1
C2
2022-12-21 10:59:12.898 D/DBINFO_STG1: Meeting is MEET2 Menu is M2 it has 2 courses. They are:-
C2
C3
2022-12-21 10:59:12.904 D/DBINFO_STG2: Meeting is MEET1 Menu is M1 it has 2 courses. They are:-
C1
C2
2022-12-21 10:59:12.904 D/DBINFO_STG2: Meeting is MEET2 Menu is M2 it has 2 courses. They are:-
C2
C3
i.e. the errant 3rd meeting did not get inserted and processing contibued allowing the 2nd output of all of the PopulatedMeetings (STG2).

JPQL - Joins - MultipleTables and empty ResultList

I have a query in JPQL through 5 tables, but if one of the table is NULL, the whole query fails and resultList is empty and it throws the exception. On the other hand if all tables do not contain null, it works as expected.
How to implement it to return all objects where table is not null and objects where is null as null? So I would get - Object1[], null, null, null for example... and not only empty result list...
Thank you very much :)
public List<Object[]> getAdditionalInformation(String ppin) {
Query query = em.createQuery("SELECT p, pl, r, d, do FROM Patient p JOIN p.placements pl JOIN pl.room r"
+ " JOIN r.department d JOIN d.doctors do where p.pin = :ppin");
query.setParameter("ppin", ppin);
return query.getResultList();
}
#Transactional
public AdditionalPD getAdditional(String ppin) {
List<Object[]> list = hr.getAdditionalInformation(ppin);
AdditionalPD adp = new AdditionalPD();
Patient patient = null;
Placement placement = null;
Room room = null;
Department department = null;
Doctor doctor = null;
for(Object[] object : list) {
patient = (Patient) object[0];
placement = (Placement) object[1];
room = (Room) object[2];
department = (Department) object[3];
doctor = (Doctor) object[4];
}
adp.setPatientFirstName(patient.getFirstName());
adp.setPatientLastName(patient.getLastName());
adp.setAge(countAge(ppin));
adp.setFrom(placement.getFrom());
adp.setTo(placement.getTo());
adp.setRoomName(room.getName());
adp.setDepartmentName(department.getName());
adp.setDoctorFirstName(doctor.getFirstName());
adp.setDoctorLastName(doctor.getLastName());
return adp;
}
#GetMapping("/additional/pin/{ppin}")
public String additionalInformation(#PathVariable String ppin, Model model) {
AdditionalPD adp = has.getAdditional(ppin);
model.addAttribute("adp", adp);
return "additional";
}
Use LEFT JOIN instead of JOIN. JPQL joins are INNER JOINs by default.

Am I approaching this correctly?

JavaFX 8 – FXML – TableView – TableColumn
I have the following objects
CourseResult
SimpleStringProperty CourseID
SimpleStringProperty CourseName
SimpleStringProperty Grade
SimpleIntegerProperty Credits
ATableRow
SimpleStringProperty StudentID
SimpleStringProperty StudentName
CourseResult[] AResult // Occurs 1 to 20.
In my program
javafx.collections.ObservableList<ATableRow> TableData = javafx.collections.FXCollections.observableArrayList();
I populate this Observable list from the database and I am able to see all the values perfectly in debugger.
I create the Tableview and add columns.
public void createTableForThisSemester(int thisSemester, int numberOfCourses, javafx.collections.ObservableList<AResultRow> TableRows) {
TableView<AResultRow> thisTable = new TableView<>();
TableColumn<AResultRow, String> tcolRollNo = new TableColumn<>("Roll Number");
tcolRollNo.setEditable(false);
tcolRollNo.setPrefWidth(120);
TableColumn<AResultRow, String> tcolName = new TableColumn<>("Student Name");
tcolName.setEditable(false);
tcolName.setPrefWidth(350);
tcolRollNo.setCellValueFactory(cellData -> cellData.getValue().StudentIDProperty());
tcolName.setCellValueFactory(cellData -> cellData.getValue().StudentNameProperty());
boolean xyz = thisTable.getColumns().addAll(tcolRollNo, tcolName);
// TableColumn[] courseColumn = new TableColumn[numberOfCourses];
for (int courseNo = 0; courseNo < numberOfCourses; courseNo++) {
String colName = getASemesterCourse(thisSemester, courseNo).getCourseID();
TableColumn<AResultRow, String> thisColumn = new TableColumn<>(colName);
thisColumn.setPrefWidth(80);
thisColumn.setStyle("-fx-alignment: CENTER; font-weight:bold;");
thisColumn.setCellValueFactory(cellData -> cellData.getValue().courseGradeProperty(courseNo));
boolean retVal = thisTable.getColumns().addAll(thisColumn);
}
// System.out.println("# of Rows in Table [" + thisSemester + "] = " + TableRows.size());
thisTable.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
thisTable.setItems(TableRows);
ScrollPane thisScrollPane = new ScrollPane();
thisScrollPane.setFitToWidth(true);
thisScrollPane.setFitToHeight(true);
thisScrollPane.setMinHeight((theDetails.getHeight() - 25));
thisScrollPane.setMaxHeight((theDetails.getHeight() - 25));
thisScrollPane.setMinWidth((theDetails.getWidth() - 25));
thisScrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);
Tab thisTab = tabs.getTabs().get(thisSemester);
thisTab.setContent(thisScrollPane);
thisScrollPane.setContent(thisTable);
}
Columns StudentID and Name are perfectly populated. But the Results are not being populated in
thisColumn.setCellValueFactory(cellData -> cellData.getValue().courseGradeProperty(courseNo));
I get this error in Netbeans for the line shown above. "Local Variables referenced from a lambda expression must be final or effectively final".
Remember, the GRADE[courseNo] field is a String and is populated.
How to show this value in the TABLE.
I have been trying various methods, like storing this value in a temp String... etc. etc.

LINQ - How to read ID which is Autonumber after submitting the data

I am working on LINQ. and in one transaction I have to update three different tables.
e.g A(A1,A2,A3) B(B1,B2) AB(A1,B1)
here B1 is autonumber in my database. I want to submit all the changes together. so in one data context I wrote
using (BBBDataContext DC= new BBBDataContext())
{
A tba = new A()
{
A1 = this.A1,
A2 = this.A2,
A3 = this.A3,
};
DC.A.InsertOnSubmit(tba);
B tbb= new B()
{
B2 = this.B2,
};
DC.B.InsertOnSubmit(tbb);
// NOW i WONT B1(WHICH IS AUTONUMBER) FROM B SO THAT I USE IT IN MY NEXT TABLE.
AB tbab = new AB()
{
A1 = this.A1,
B1 = ??????,
};
DC.AB.InsertOnSubmit(tbab);
//FINALLY I WILL WRITE SUBMIT CHANGES SO MY ALL TABLES GET CHANGES SAME TIME
DC.SubmitChanges();
}
Que: what should I write # the place of ?????. for B1 in AB table??
Short answer: B
Bit longer answer:
When you create the object and add it you won't get the ID before you commit. So what you do is reference the object and not the ID property of the object.
class A {
public int Id { get;set;}
public ICollection <B> Bees { get;set;}
}
class B {
public int Id { get;set;}
public int InstanceOfAId { get;set;}
public A InstanceOfA { get;set;}
}
var a = new A();
var b = new B();
b.InstanceOfA = a;
Depending on your model you will define a relationship. In code first you could do it this way:
EntityTypeConfiguration<B> cfgB = new EntityTypeConfiguration<B>();
cfgB.HasRequired(p => p.InstanceOfA).WithMany(p => p.Bees)
.HasForeignKey(p => p.InstanceOfAId);
In EDMX you can do the same in the designer.
You will use InstanceOfA to assign to when inserting, after that InstanceOfAId will always hold the Id value. When retrieving data InstanceOfA will only be filled when requested.
You can use it like this:
var x = DC.B.Include(p=>p.A);
or
var x = DC.B.Select(p=> new { Id = p.Id, A_Id = p.A.Id});
or
var x = DC.A.Select(p=> new { Id = p.Id, BeeCount = p.Bees.Count()});

How to perform "complex" join using Linq

I need to join two objects (tables) A and B. For any A there can be zero to many B's. The query needs the return one row per A.
The B's I want to order before the join to be able to select the needed row from B's following a certain condition. Say B has a column Type. If there is a Type 1 then that's the B I need, if not: Type 2 must be selected, etc.
Now I think about it, I am not sure how I would to this even in T-sql.
I think something like this:
SELECT A.*
FROM A LEFT JOIN (
SELECT * FROM B AS B1 WHERE B1.Type = (SELECT TOP 1 B2.Type FROM B AS B2
WHERE B2.JoinID = B1.JoinID
ORDER BY B2.Type )
) AS B ON B.JoinID = A.JoinID
[edit]
With the answer of sgtz I've tried to make it work. If have to make an additional step because the field I want to order by is not present. I add this field in step 1, in step 2 I make a selection of the keys and join everything in step 3, but there I receive an error "The type of one of the expressions in the join clause is incorrect. Type inference failed in the call to 'GroupJoin'." on join "join a in adressen1 on new { b.TopRelatieID..."
var adressen1 = from a in db.Adres
select new
{
RelatieAdres = a,
Sortering = (int)(a.AdresType.Code == codeVestAdres ?
1 : a.AdresType.Code == codePostAdres ?
2 : (100 + (int)a.AdresType.Code.ToCharArray()[0]))
};
var adressen2 = from b in adressen1
group b by new { RelatieID = b.RelatieAdres.RelatieID } into p
let TopAdresType = p.Min(at => at.Sortering)
select new { TopRelatieID = p.Key.RelatieID, TopAdresType };
var q = from k in db.Klants
join b in adressen2 on k.RelatieID equals b.TopRelatieID into b_join
from b in b_join.DefaultIfEmpty()
join a in adressen1 on new { b.TopRelatieID, b.TopAdresType } equals new { a.RelatieAdres.RelatieID, a.Sortering } into a_join
from a in a_join.DefaultIfEmpty()
Here's a worked example. I did it two stages.
[Test]
public void Test333()
{
List<Order> O;
var M = Prepare333Data(out O);
var OTop = from o in O
group o by new {id=o.id, orderid=o.orderid}
into p
let topType = p.Min(tt => tt.type)
select new Order(p.Key.id, p.Key.orderid, topType);
var ljoin = from m in M
join t in OTop on m.id equals t.id into ts
from u in ts.DefaultIfEmpty()
select new {u.id, u.orderid, u.type};
}
public class Manufacturer
{
public Manufacturer(int id, string name)
{
this.id = id;
this.name = name;
}
public int id { get; set; }
public string name { get; set; }
}
public class Order
{
public Order(int id, int orderid, int type)
{
this.orderid = orderid;
this.id = id;
this.type = type;
}
public int orderid { get; set; }
public int id { get; set; }
public int type { get; set; }
}
private List<Manufacturer> Prepare333Data(out List<Order> O)
{
var M = new List<Manufacturer>() {new Manufacturer(1, "Abc"), new Manufacturer(2, "Def")};
O = new List<Order>()
{
new Order(1, 1, 2),
new Order(1, 2, 2),
new Order(1, 2, 3),
new Order(2, 3, 1)
,
new Order(2, 3, 1)
,
new Order(2, 3, 2)
};
return M;
}
response to comments:
your "new {" creates a new anonymous type. Two anonymous types created by difference processes are said to have the same signature if types are declared in the same order and they have the same type definition (i.e. int matches int, not int matches short). I haven't tested this scenario extensively in LINQ.
That's why I worked with real concrete classes, and not anon types within the JOIN portion. There's probably a way to rework it with pure LINQ, but I don't know what that is yet. I'll post you a response if it occurs to me okay.
I'd suggest using concrete classes too for now.
i.e. instead of
*new {*
when doing joins, always use
*new CLASSNAME(){prop1="abc",prop2="123"*
It's a little bit longer, but safer... safer at least until we work out what is going on inside the LINQ internals.
To be meaningful, you should add at least something to query result, not only A.*. Otherwise you'll have a copy of A with some rows possibly duplicated. If I understood the question correctly, this SQL query should work:
SELECT DISTINCT A.*, B.Type
FROM A LEFT JOIN
(SELECT TOP (1) JoinID, Type
FROM B
ORDER BY Type
GROUP BY JoinID, Type
) AS B ON A.JoinID = B.JoinID
Translated to LINQ, it is (UPDATED)
(from a in As
join b in
(from b1 in Bs
orderby b1.Type
group b1 by b1.JoinID into B1
from b11 in B1
group b11 by b11.Type into B11
from b111 in B11
select new { b111.JoinID, b111.Type }).Take(1)
on a.JoinID equals b.JoinID into a_b
from ab in a_b.DefaultIfEmpty()
select new { a_b.JoinID, /*all other a properties*/ a_b.Type }).Distinct()
LINQ may not work 100% correct, but you should grab the idea.

Resources