Câu trả lời:
transient
Từ khóa của Java được sử dụng để biểu thị rằng một trường không được tuần tự hóa, trong khi @Transient
chú thích của JPA được sử dụng để chỉ ra rằng một trường không được duy trì trong cơ sở dữ liệu, nghĩa là ngữ nghĩa của chúng là khác nhau.
Bởi vì chúng có ý nghĩa khác nhau. Các @Transient
chú thích cho các nhà cung cấp JPA không tồn tại bất kỳ (không transient
) thuộc tính. Cái kia nói với khung tuần tự hóa để không tuần tự hóa một thuộc tính. Bạn có thể muốn có một @Transient
tài sản và vẫn tuần tự hóa nó.
Như những người khác đã nói, @Transient
được sử dụng để đánh dấu các trường không nên tồn tại. Xem xét ví dụ ngắn này:
public enum Gender { MALE, FEMALE, UNKNOWN }
@Entity
public Person {
private Gender g;
private long id;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public long getId() { return id; }
public void setId(long id) { this.id = id; }
public Gender getGender() { return g; }
public void setGender(Gender g) { this.g = g; }
@Transient
public boolean isMale() {
return Gender.MALE.equals(g);
}
@Transient
public boolean isFemale() {
return Gender.FEMALE.equals(g);
}
}
Khi lớp này được cung cấp cho JPA, nó vẫn tồn tại gender
và id
nhưng không cố gắng duy trì các phương thức boolean của trình trợ giúp - mà không có @Transient
hệ thống cơ bản sẽ phàn nàn rằng lớp Entity Person
bị thiếu setMale()
và setFemale()
các phương thức và do đó sẽ không tồn Person
tại.
Mục đích là khác nhau:
Các transient
từ khóa và @Transient
chú thích có hai mục đích khác nhau: một thỏa thuận với serialization và một thỏa thuận với sự kiên trì . Là lập trình viên, chúng tôi thường kết hợp hai khái niệm này thành một, nhưng nói chung điều này không chính xác. Sự kiên định đề cập đến đặc tính của trạng thái tồn tại lâu hơn quá trình tạo ra nó. Tuần tự hóa trong Java đề cập đến quá trình mã hóa / giải mã trạng thái của đối tượng dưới dạng luồng byte.
Các transient
từ khóa là một điều kiện mạnh hơn @Transient
:
Nếu một trường sử dụng transient
từ khóa, trường đó sẽ không được tuần tự hóa khi đối tượng được chuyển đổi thành luồng byte. Hơn nữa, vì JPA coi các trường được đánh dấu bằng transient
từ khóa là có @Transient
chú thích, nên trường cũng sẽ không được JPA duy trì.
Mặt khác, các trường được chú thích @Transient
một mình sẽ được chuyển đổi thành luồng byte khi đối tượng được tuần tự hóa, nhưng nó sẽ không được JPA duy trì. Do đó, transient
từ khóa là một điều kiện mạnh hơn @Transient
chú thích.
Thí dụ
Điều này đặt ra câu hỏi: Tại sao mọi người muốn tuần tự hóa một trường không tồn tại trong cơ sở dữ liệu của ứng dụng? Thực tế là tuần tự hóa được sử dụng không chỉ là sự kiên trì . Trong một ứng dụng Java doanh nghiệp cần có một cơ chế để trao đổi các đối tượng giữa các thành phần phân tán ; serialization cung cấp một giao thức truyền thông chung để xử lý việc này. Do đó, một lĩnh vực có thể chứa thông tin quan trọng cho mục đích giao tiếp giữa các thành phần; nhưng cùng một lĩnh vực có thể không có giá trị từ quan điểm kiên trì.
Ví dụ: giả sử thuật toán tối ưu hóa được chạy trên máy chủ và giả sử thuật toán này mất vài giờ để hoàn thành. Đối với khách hàng, việc có một bộ giải pháp cập nhật nhất là rất quan trọng. Vì vậy, khách hàng có thể đăng ký vào máy chủ và nhận các bản cập nhật định kỳ trong giai đoạn thực hiện thuật toán. Những cập nhật này được cung cấp bằng cách sử dụng ProgressReport
đối tượng:
@Entity
public class ProgressReport implements Serializable{
private static final long serialVersionUID = 1L;
@Transient
long estimatedMinutesRemaining;
String statusMessage;
Solution currentBestSolution;
}
Các Solution
lớp có thể trông như thế này:
@Entity
public class Solution implements Serializable{
private static final long serialVersionUID = 1L;
double[][] dataArray;
Properties properties;
}
Các máy chủ vẫn tồn tại mỗi ProgressReport
cơ sở dữ liệu của nó. Máy chủ không quan tâm để tiếp tục estimatedMinutesRemaining
, nhưng khách hàng chắc chắn quan tâm đến thông tin này. Do đó, estimatedMinutesRemaining
được chú thích bằng cách sử dụng @Transient
. Khi trận chung kết Solution
được định vị bằng thuật toán, nó được JPA duy trì trực tiếp mà không sử dụng a ProgressReport
.
@Unpersisted
.
@Ephemeral
. Theo Merriam Webster: Khi phù du lần đầu tiên được in bằng tiếng Anh vào những năm 1600, "đó là một thuật ngữ khoa học áp dụng cho các cơn sốt ngắn hạn, và sau đó, đối với các sinh vật (như côn trùng và hoa) với tuổi thọ rất ngắn. , nó có được một ý nghĩa mở rộng đề cập đến bất cứ điều gì thoáng qua và ngắn ngủi (như trong "thú vui phù du"). "
transient
các lĩnh vực là hoàn toàn có @Transient
chú thích. Vì vậy, nếu bạn sử dụng transient
từ khóa để ngăn chặn việc tuần tự hóa một trường thì nó cũng sẽ không kết thúc trong cơ sở dữ liệu.
Nếu bạn chỉ muốn một lĩnh vực sẽ không được duy trì, cả công việc tạm thời và @Transient đều hoạt động. Nhưng câu hỏi là tại sao @Transient kể từ khi thoáng qua đã tồn tại.
Bởi vì trường @Transient vẫn sẽ được tuần tự hóa!
Giả sử bạn tạo một thực thể, thực hiện một số tính toán tiêu thụ CPU để có kết quả và kết quả này sẽ không lưu trong cơ sở dữ liệu. Nhưng bạn muốn gửi thực thể đến các ứng dụng Java khác để JMS sử dụng, thì bạn nên sử dụng @Transient
, không phải từ khóa JavaSE transient
. Vì vậy, các máy thu chạy trên các máy ảo khác có thể tiết kiệm thời gian của chúng để tính lại.
Tôi sẽ cố gắng trả lời câu hỏi "tại sao". Hãy tưởng tượng một tình huống trong đó bạn có một cơ sở dữ liệu khổng lồ với rất nhiều cột trong một bảng và dự án / hệ thống của bạn sử dụng các công cụ để tạo các thực thể từ cơ sở dữ liệu. (Hibernate có những thứ đó, v.v ...) Bây giờ, giả sử rằng theo logic kinh doanh của bạn, bạn cần một lĩnh vực cụ thể KHÔNG được tồn tại. Bạn phải "cấu hình" thực thể của mình theo một cách cụ thể. Mặc dù từ khóa Transient hoạt động trên một đối tượng - vì nó hoạt động trong ngôn ngữ java, nhưng @Transient chỉ được thiết kế để trả lời các tác vụ chỉ liên quan đến các tác vụ bền bỉ.