JPA models persistent state via entities. You cannot tag relationships with their own state. If you find yourself wanting to do so then that's a sign that you need to interpose an additional entity.
Typical procedures for that are described among the answers to JPA 2.0 many-to-many with extra column. The same approach can be used for a one-to-many in which the relationship is modeled via a join table, but if the relationship is one-to-many then the data can ordinarily be recorded in the entities on the "many" side instead, since each of those is specific to / owned by exactly one entity on the "one" side anyway.
As to the the specifics of your question:
JobsStatus is a static table in database
I take you to mean that this table is never modified. It serves only to enumerate the allowed status codes such as "COMPLETED". (A more common variation also associates those codes with surrogate primary keys, but that's not essential.)
But if it is never modified, then it is not useful for this table to have the sysDate
column that is null for all rows. This carries no information, and never will carry any information because these rows are not supposed to be modified. Moreover, if the database must support dates for the same status for different jobs at the same time, then this column is not sufficient anyway.
i try to update like this:
JobsStatus jobStatus = new IRJobsStatus();
jobStatus.setJobStatus("INSERTED");
jobStatus.setSysDate(new java.sql.Date(new java.util.Date().getTime()));
jobStatusList.add(jobStatus);
If you set an entity property such as via jobStatus.setSysDate()
then you should expect any persistent representation to be stored in the entity's table. Moreover, if you create a new entity (i.e. a JobStatus
) and persist it, then you should expect a new row in that entity's table. That would not be appropriate for my understanding of a "static" table.
Overall, I think this is exactly the situation described in the linked question, but you're coming at it from a different angle. The things with which your Job
s have a one-to-many relationship are not statuses, but status dates. And, I presume, there may be many status dates (for different jobs) with for the same status. Thus, the multiplicities are:
Job (1) --- (many) JobStatusDate (many) --- (1) JobStatus
If you collapse that to look at the Job:JobStatus multiplicity, it is many-to-many.
I hope the direction I'm heading is already clear. You need to introduce a new entity to carry the dates of each job's various statuses. That can be structured multiple ways, but the one that most closely matches your database design would be something like this:
@Entity
public class Job {
@Id
private Integer jobId;
@OneToMany(mappedBy = job)
private List<JobStatusDate> statusDates;
}
@Entity
public class JobStatusDate {
@Id
@ManyToOne
private Job job;
@Id
@ManyToOne
private JobStatus status;
private Date date;
}
@Entity
public class JobStatus {
@Id
private String status;
// optional:
@OneToMany(mappedBy = status)
private List<JobStatusDate> statusDates;
}
Alternatively, if the application needs built-in knowledge of the valid job status codes (likely, since I anticipate that they are associated with specific business logic) then you could consider dropping the JobStatus entity (but keeping the table and the FK relationship in the database). Then JobStatusDate
would have a plain String
status code instead of a relationship with a JobStatus
entity. The FK relationship retained in the DB would prevent invalid status codes from being recorded, which I guess is its intended purpose already.
In that event, you might consider going even further by mapping the status codes to an appropriate Java enum
instead of to a String
. The ultimate result might go as far as this:
public enum JobStatus {
COMPLETED, ERROR, INSERTED, PROCESSING, VALIDATED, VALIDATING
}
@Entity
public class Job {
@Id
private Integer jobId;
@OneToMany(mappedBy = job)
@MapKey(name = status)
private Map<JobStatus, JobStatusDate> statusDates;
}
@Entity
public class JobStatusDate {
@Id
@ManyToOne
private Job job;
@Id
@Enumerated(EnumType.STRING)
private JobStatus status;
private Date date;
}
// No JobStatus entity
Notably, this allows you to map the Job
: JobStatusDate
relationship as a map, which would be a convenience for many of the kinds of things I anticipate you might want to do.